prism 1.5.1 → 1.8.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 (68) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +60 -1
  3. data/Makefile +12 -5
  4. data/README.md +2 -1
  5. data/config.yml +30 -4
  6. data/docs/build_system.md +2 -2
  7. data/docs/cruby_compilation.md +1 -1
  8. data/docs/design.md +2 -2
  9. data/docs/parser_translation.md +1 -1
  10. data/docs/releasing.md +4 -25
  11. data/docs/ruby_api.md +1 -0
  12. data/ext/prism/api_node.c +7 -3
  13. data/ext/prism/extconf.rb +1 -1
  14. data/ext/prism/extension.c +10 -2
  15. data/ext/prism/extension.h +1 -1
  16. data/include/prism/ast.h +85 -21
  17. data/include/prism/diagnostic.h +3 -0
  18. data/include/prism/options.h +8 -2
  19. data/include/prism/parser.h +3 -0
  20. data/include/prism/version.h +3 -3
  21. data/include/prism.h +1 -1
  22. data/lib/prism/compiler.rb +152 -152
  23. data/lib/prism/dot_visitor.rb +5 -0
  24. data/lib/prism/dsl.rb +2 -2
  25. data/lib/prism/ffi.rb +11 -3
  26. data/lib/prism/inspect_visitor.rb +1 -0
  27. data/lib/prism/lex_compat.rb +17 -75
  28. data/lib/prism/lex_ripper.rb +64 -0
  29. data/lib/prism/node.rb +1157 -15
  30. data/lib/prism/parse_result.rb +2 -15
  31. data/lib/prism/polyfill/scan_byte.rb +1 -1
  32. data/lib/prism/polyfill/warn.rb +16 -22
  33. data/lib/prism/reflection.rb +1 -1
  34. data/lib/prism/serialize.rb +8 -5
  35. data/lib/prism/translation/parser/compiler.rb +16 -16
  36. data/lib/prism/translation/parser.rb +12 -3
  37. data/lib/prism/translation/parser_current.rb +5 -3
  38. data/lib/prism/translation/parser_versions.rb +36 -0
  39. data/lib/prism/translation/ripper/lexer.rb +46 -0
  40. data/lib/prism/translation/ripper.rb +27 -4
  41. data/lib/prism/translation/ruby_parser.rb +55 -20
  42. data/lib/prism/translation.rb +5 -3
  43. data/lib/prism/visitor.rb +152 -152
  44. data/lib/prism.rb +21 -1
  45. data/prism.gemspec +5 -7
  46. data/rbi/prism/dsl.rbi +3 -3
  47. data/rbi/prism/node.rbi +21 -8
  48. data/rbi/prism/translation/parser_versions.rbi +23 -0
  49. data/sig/prism/dsl.rbs +2 -2
  50. data/sig/prism/node.rbs +19 -8
  51. data/sig/prism.rbs +4 -0
  52. data/src/diagnostic.c +7 -1
  53. data/src/encoding.c +172 -67
  54. data/src/node.c +9 -0
  55. data/src/options.c +17 -7
  56. data/src/prettyprint.c +16 -0
  57. data/src/prism.c +1335 -1958
  58. data/src/serialize.c +7 -1
  59. data/src/token_type.c +2 -2
  60. data/src/util/pm_constant_pool.c +1 -1
  61. data/src/util/pm_string.c +6 -8
  62. metadata +7 -9
  63. data/lib/prism/translation/parser33.rb +0 -13
  64. data/lib/prism/translation/parser34.rb +0 -13
  65. data/lib/prism/translation/parser35.rb +0 -13
  66. data/rbi/prism/translation/parser33.rbi +0 -6
  67. data/rbi/prism/translation/parser34.rbi +0 -6
  68. data/rbi/prism/translation/parser35.rbi +0 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 71ec272c4385e48796979636d3d37547841cf1b27de8d61dbfc69b9300fefc5e
4
- data.tar.gz: 58d2105009b3edfe9246deffaec5989ba8a63da2f68d770b80393e4970bfa89a
3
+ metadata.gz: 2344922b08aa30076aab32c5a92e0d7f21a05f03bb85d089cc69e228a71e3b20
4
+ data.tar.gz: 7a44533dd2827ec9f6c31fc69c533c9f90b88520aef71219a348aa61fa460fbd
5
5
  SHA512:
6
- metadata.gz: ad2f9f3ca25f79b5414f8144b23a529ae4cbe23e7f5fc619da54cea7676ecfc93f03bd7548824d523352765d66fe157f67fb989350c4f4b4a6f29782c796539e
7
- data.tar.gz: 9e447578eb512232efe4c9263adc786701cbecbd94f2f4f6d87f2ec5f0961a5ec568acbe20aef23e810fe8f7998a8fd4f9c522cb9a9b986074f7a6e8baa4f6eb
6
+ metadata.gz: c278e7b881b89f51150850df09062d9a9bd5e5076746e4b86ab199729a588f8aa346e12b6ba9b95dc0cf53592866bf216977bbb7da10cef6bd8a018681e9f45f
7
+ data.tar.gz: '009dee7695d1f7d58adb68d3829f97ecff445cc0eb8509526979f938932e553abdc2ba601049df67b8b29a75b7d542a9fb06d4c1984131d6f60e2ac9e3cf83c2'
data/CHANGELOG.md CHANGED
@@ -4,8 +4,63 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [1.8.0] - 2026-01-12
8
+
9
+ ### Added
10
+
11
+ - Optimize ruby visitor.
12
+ - Report unterminated construct errors at opening token.
13
+
14
+ ### Changed
15
+
16
+ - Correctly expose ripper state.
17
+ - Use one file for versioned parser classes.
18
+ - Fix denominator of rational float literal.
19
+ - Decouple ripper translator from ripper library.
20
+ - Sync Prism::Translation::ParserCurrent with Ruby 4.0.
21
+
7
22
  ## [Unreleased]
8
23
 
24
+ ## [1.7.0] - 2025-12-18
25
+
26
+ ### Added
27
+
28
+ - Support `4.1` as a version option.
29
+ - Add `equal_loc` to `CallNode`.
30
+ - Add `len()`/`is_empty()` to `ConstantList` and `NodeList` in the Rust API.
31
+
32
+ ### Changed
33
+
34
+ - Rename version `3.5` to version `4.0`.
35
+ - Fix compiling the gem from source on Windows.
36
+ - Fix parsing of unary method calls like `42.~@`.
37
+ - Reject `def f a, (b) = 1`.
38
+ - Reject endless method as a block parameter default.
39
+ - Reject variable capture in alternative pattern.
40
+ - Many fixes in regards to memory safety, found through fuzzing.
41
+ - Many fixes to better handle invalid syntax, also found through fuzzing.
42
+ - Fix the ruby version used by the `ripper` translator.
43
+ - Fix `ruby_parser` translation comment processing.
44
+
45
+ ## [1.6.0] - 2025-10-16
46
+
47
+ ### Added
48
+
49
+ - Add support for passing `"current"` as the version option to `Prism.*` APIs.
50
+
51
+ ### Changed
52
+
53
+ - Remove a compiler warning for a missing unsigned cast for a shift value.
54
+
55
+ ## [1.5.2] - 2025-10-09
56
+
57
+ ### Changed
58
+
59
+ - Fix character literal forced encoding when a unicode escape sequence is used.
60
+ - Reject `1 if foo = bar baz`.
61
+ - Clear static literal flag on interpolated strings.
62
+ - Reject optional argument/endless method definition ambiguity.
63
+
9
64
  ## [1.5.1] - 2025-09-13
10
65
 
11
66
  ### Changed
@@ -676,7 +731,11 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
676
731
 
677
732
  - 🎉 Initial release! 🎉
678
733
 
679
- [unreleased]: https://github.com/ruby/prism/compare/v1.5.1...HEAD
734
+ [unreleased]: https://github.com/ruby/prism/compare/v1.8.0...HEAD
735
+ [1.8.0]: https://github.com/ruby/prism/compare/v1.7.0...v1.8.0
736
+ [1.7.0]: https://github.com/ruby/prism/compare/v1.6.0...v1.7.0
737
+ [1.6.0]: https://github.com/ruby/prism/compare/v1.5.2...v1.6.0
738
+ [1.5.2]: https://github.com/ruby/prism/compare/v1.5.1...v1.5.2
680
739
  [1.5.1]: https://github.com/ruby/prism/compare/v1.5.0...v1.5.1
681
740
  [1.5.0]: https://github.com/ruby/prism/compare/v1.4.0...v1.5.0
682
741
  [1.4.0]: https://github.com/ruby/prism/compare/v1.3.0...v1.4.0
data/Makefile CHANGED
@@ -15,6 +15,7 @@ CFLAGS := -g -O2 -std=c99 -Wall -Werror -Wextra -Wpedantic -Wundef -Wconversion
15
15
  JAVA_WASM_CFLAGS := -g -Oz -std=c99 -Wall -Werror -Wextra -Wpedantic -Wundef -Wconversion -Wno-missing-braces -fPIC -fvisibility=hidden -Wimplicit-fallthrough $(JAVA_WASM_CFLAGS)
16
16
  CC ?= cc
17
17
  AR ?= ar
18
+ ARFLAGS ?= -r$(V0:1=v)
18
19
  WASI_SDK_PATH := /opt/wasi-sdk
19
20
 
20
21
  MAKEDIRS ?= mkdir -p
@@ -38,11 +39,17 @@ build/libprism.$(SOEXT): $(SHARED_OBJECTS)
38
39
 
39
40
  build/libprism.a: $(STATIC_OBJECTS)
40
41
  $(ECHO) "building $@ with $(AR)"
41
- $(Q) $(AR) $(ARFLAGS) $@ $(STATIC_OBJECTS) $(Q1:0=>/dev/null)
42
+ $(Q) $(AR) $(ARFLAGS) $@ $(STATIC_OBJECTS)
42
43
 
43
44
  javascript/src/prism.wasm: Makefile $(SOURCES) $(HEADERS)
44
45
  $(ECHO) "building $@"
45
- $(Q) $(WASI_SDK_PATH)/bin/clang --sysroot=$(WASI_SDK_PATH)/share/wasi-sysroot/ $(DEBUG_FLAGS) -DPRISM_EXPORT_SYMBOLS -D_WASI_EMULATED_MMAN -lwasi-emulated-mman $(CPPFLAGS) $(CFLAGS) -Wl,--export-all -Wl,--no-entry -mexec-model=reactor -o $@ $(SOURCES)
46
+ $(Q) $(WASI_SDK_PATH)/bin/clang --sysroot=$(WASI_SDK_PATH)/share/wasi-sysroot/ \
47
+ $(DEBUG_FLAGS) \
48
+ -DPRISM_EXPORT_SYMBOLS -DPRISM_EXCLUDE_PRETTYPRINT -DPRISM_EXCLUDE_JSON -DPRISM_EXCLUDE_PACK \
49
+ -D_WASI_EMULATED_MMAN -lwasi-emulated-mman $(CPPFLAGS) $(CFLAGS) \
50
+ -Wl,--export-all -Wl,--gc-sections -Wl,--strip-all -Wl,--lto-O3 -Wl,--no-entry -mexec-model=reactor \
51
+ -Oz -g0 -flto -fdata-sections -ffunction-sections \
52
+ -o $@ $(SOURCES)
46
53
 
47
54
  java-wasm/src/test/resources/prism.wasm: Makefile $(SOURCES) $(HEADERS)
48
55
  $(ECHO) "building $@"
@@ -62,12 +69,12 @@ build/fuzz.%: $(SOURCES) fuzz/%.c fuzz/fuzz.c
62
69
  $(ECHO) "building $* fuzzer"
63
70
  $(Q) $(MAKEDIRS) $(@D)
64
71
  $(ECHO) "building main fuzz binary"
65
- $(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 $@ $^
72
+ $(Q) afl-clang-lto $(DEBUG_FLAGS) $(CPPFLAGS) $(CFLAGS) $(FUZZ_FLAGS) -O0 -fsanitize-ignorelist=fuzz/asan.ignore -fsanitize=fuzzer,address -ggdb3 -std=c99 -Iinclude -o $@ $^
66
73
  $(ECHO) "building cmplog binary"
67
- $(Q) AFL_HARDEN=1 AFL_LLVM_CMPLOG=1 afl-clang-lto $(DEBUG_FLAGS) $(CPPFLAGS) $(CFLAGS) $(FUZZ_FLAGS) -O0 -fsanitize-ignorelist=fuzz/asan.ignore -fsanitize=fuzzer,address -ggdb3 -std=c99 -Iinclude -o $@.cmplog $^
74
+ $(Q) AFL_LLVM_CMPLOG=1 afl-clang-lto $(DEBUG_FLAGS) $(CPPFLAGS) $(CFLAGS) $(FUZZ_FLAGS) -O0 -fsanitize-ignorelist=fuzz/asan.ignore -fsanitize=fuzzer,address -ggdb3 -std=c99 -Iinclude -o $@.cmplog $^
68
75
 
69
76
  build/fuzz.heisenbug.%: $(SOURCES) fuzz/%.c fuzz/heisenbug.c
70
- $(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 $@ $^
77
+ $(Q) afl-clang-lto $(DEBUG_FLAGS) $(CPPFLAGS) $(CFLAGS) $(FUZZ_FLAGS) -O0 -fsanitize-ignorelist=fuzz/asan.ignore -fsanitize=fuzzer,address -ggdb3 -std=c99 -Iinclude -o $@ $^
71
78
 
72
79
  fuzz-debug:
73
80
  $(ECHO) "entering debug shell"
data/README.md CHANGED
@@ -116,7 +116,7 @@ Prism has been integrated into the majority of Ruby runtimes, many libraries, an
116
116
  * [JRuby](https://github.com/jruby/jruby/pull/8103) (via Java)
117
117
  * [Natalie](https://github.com/natalie-lang/natalie/pull/1213) (via C++ and Ruby)
118
118
  * [Opal](https://github.com/opal/opal/pull/2642) (via Ruby and WASM)
119
- * [TruffleRuby](https://github.com/oracle/truffleruby/issues/3117) (via Java)
119
+ * [TruffleRuby](https://github.com/truffleruby/truffleruby/issues/3117) (via Java)
120
120
 
121
121
  ### Libraries
122
122
 
@@ -135,6 +135,7 @@ Prism has been integrated into the majority of Ruby runtimes, many libraries, an
135
135
  * [sorbet-eraser](https://github.com/kddnewton/sorbet-eraser/pull/25)
136
136
  * [synvert](https://github.com/xinminlabs/synvert-core-ruby)
137
137
  * [typeprof](https://github.com/ruby/typeprof)
138
+ * [unparser](https://github.com/mbj/unparser) (via parser translator)
138
139
 
139
140
  ### Applications
140
141
 
data/config.yml CHANGED
@@ -60,6 +60,7 @@ errors:
60
60
  - CONDITIONAL_WHILE_PREDICATE
61
61
  - CONSTANT_PATH_COLON_COLON_CONSTANT
62
62
  - DEF_ENDLESS
63
+ - DEF_ENDLESS_PARAMETERS
63
64
  - DEF_ENDLESS_SETTER
64
65
  - DEF_NAME
65
66
  - DEF_PARAMS_TERM
@@ -218,6 +219,7 @@ errors:
218
219
  - PARAMETER_WILD_LOOSE_COMMA
219
220
  - PATTERN_ARRAY_MULTIPLE_RESTS
220
221
  - PATTERN_CAPTURE_DUPLICATE
222
+ - PATTERN_CAPTURE_IN_ALTERNATIVE
221
223
  - PATTERN_EXPRESSION_AFTER_BRACKET
222
224
  - PATTERN_EXPRESSION_AFTER_COMMA
223
225
  - PATTERN_EXPRESSION_AFTER_HROCKET
@@ -279,6 +281,7 @@ errors:
279
281
  - UNEXPECTED_INDEX_KEYWORDS
280
282
  - UNEXPECTED_LABEL
281
283
  - UNEXPECTED_MULTI_WRITE
284
+ - UNEXPECTED_PARAMETER_DEFAULT_VALUE
282
285
  - UNEXPECTED_RANGE_OPERATOR
283
286
  - UNEXPECTED_SAFE_NAVIGATION
284
287
  - UNEXPECTED_TOKEN_CLOSE_CONTEXT
@@ -355,6 +358,8 @@ tokens:
355
358
  comment: "a newline character outside of other tokens"
356
359
  - name: PARENTHESIS_RIGHT
357
360
  comment: ")"
361
+ - name: PIPE
362
+ comment: "|"
358
363
  - name: SEMICOLON
359
364
  comment: ";"
360
365
  # Tokens from here on are not used for lookup, and can be in any order.
@@ -588,8 +593,6 @@ tokens:
588
593
  comment: "%I"
589
594
  - name: PERCENT_UPPER_W
590
595
  comment: "%W"
591
- - name: PIPE
592
- comment: "|"
593
596
  - name: PIPE_EQUAL
594
597
  comment: "|="
595
598
  - name: PIPE_PIPE
@@ -1514,6 +1517,16 @@ nodes:
1514
1517
 
1515
1518
  foo(bar)
1516
1519
  ^
1520
+ - name: equal_loc
1521
+ type: location?
1522
+ comment: |
1523
+ Represents the location of the equal sign, in the case that this is an attribute write.
1524
+
1525
+ foo.bar = value
1526
+ ^
1527
+
1528
+ foo[bar] = value
1529
+ ^
1517
1530
  - name: block
1518
1531
  type: node?
1519
1532
  kind:
@@ -1800,7 +1813,7 @@ nodes:
1800
1813
  Represents the predicate of the case statement. This can be either `nil` or any [non-void expressions](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression).
1801
1814
 
1802
1815
  case true; when false; end
1803
- ^^^^
1816
+ ^^^^
1804
1817
  - name: conditions
1805
1818
  type: node[]
1806
1819
  kind: WhenNode
@@ -2615,11 +2628,18 @@ nodes:
2615
2628
  - name: block
2616
2629
  type: node?
2617
2630
  kind: BlockNode
2631
+ comment: |
2632
+ All other arguments are forwarded as normal, except the original block is replaced with the new block.
2618
2633
  comment: |
2619
- Represents the use of the `super` keyword without parentheses or arguments.
2634
+ Represents the use of the `super` keyword without parentheses or arguments, but which might have a block.
2620
2635
 
2621
2636
  super
2622
2637
  ^^^^^
2638
+
2639
+ super { 123 }
2640
+ ^^^^^^^^^^^^^
2641
+
2642
+ If it has any other arguments, it would be a `SuperNode` instead.
2623
2643
  - name: GlobalVariableAndWriteNode
2624
2644
  fields:
2625
2645
  - name: name
@@ -3286,6 +3306,9 @@ nodes:
3286
3306
  - EmbeddedVariableNode
3287
3307
  - InterpolatedStringNode # `"a" "#{b}"`
3288
3308
  - on error: XStringNode # `<<`FOO` "bar"
3309
+ - on error: InterpolatedXStringNode
3310
+ - on error: SymbolNode
3311
+ - on error: InterpolatedSymbolNode
3289
3312
  - name: closing_loc
3290
3313
  type: location?
3291
3314
  newline: parts
@@ -4495,6 +4518,7 @@ nodes:
4495
4518
  - name: arguments
4496
4519
  type: node?
4497
4520
  kind: ArgumentsNode
4521
+ comment: "Can be only `nil` when there are empty parentheses, like `super()`."
4498
4522
  - name: rparen_loc
4499
4523
  type: location?
4500
4524
  - name: block
@@ -4510,6 +4534,8 @@ nodes:
4510
4534
 
4511
4535
  super foo, bar
4512
4536
  ^^^^^^^^^^^^^^
4537
+
4538
+ If no arguments are provided (except for a block), it would be a `ForwardingSuperNode` instead.
4513
4539
  - name: SymbolNode
4514
4540
  flags: SymbolFlags
4515
4541
  fields:
data/docs/build_system.md CHANGED
@@ -58,12 +58,12 @@ prism's `Makefile` is not used at all in CRuby. Instead, CRuby's `Makefile` is u
58
58
 
59
59
  ### Building prism as part of TruffleRuby
60
60
 
61
- [This script](https://github.com/oracle/truffleruby/blob/master/tool/import-prism.sh) imports prism sources in TruffleRuby.
61
+ [This script](https://github.com/truffleruby/truffleruby/blob/master/tool/import-prism.sh) imports prism sources in TruffleRuby.
62
62
  The script generates the templates when importing.
63
63
 
64
64
  Then when `mx build` builds TruffleRuby and the `prism` mx project inside, it runs `make`.
65
65
 
66
- Then the `prism bindings` mx project is built, which contains the [bindings](https://github.com/oracle/truffleruby/blob/vm-24.1.1/src/main/c/yarp_bindings/src/yarp_bindings.c)
66
+ Then the `prism bindings` mx project is built, which contains the [bindings](https://github.com/truffleruby/truffleruby/blob/vm-24.1.1/src/main/c/yarp_bindings/src/yarp_bindings.c)
67
67
  and links to `libprism.a` (to avoid exporting symbols, so no conflict when installing the prism gem).
68
68
 
69
69
  ### Building prism as part of JRuby
@@ -1,6 +1,6 @@
1
1
  # Compiling Prism's AST
2
2
 
3
- One important class of consumers of Prism's AST is compilers. Currently [CRuby](https://github.com/ruby/ruby), [JRuby](https://github.com/jruby/jruby), [TruffleRuby](https://github.com/oracle/truffleruby), and [Natalie](https://github.com/natalie-lang/natalie) have all built compilation code on top of Prism's AST.
3
+ One important class of consumers of Prism's AST is compilers. Currently [CRuby](https://github.com/ruby/ruby), [JRuby](https://github.com/jruby/jruby), [TruffleRuby](https://github.com/truffleruby/truffleruby), and [Natalie](https://github.com/natalie-lang/natalie) have all built compilation code on top of Prism's AST.
4
4
 
5
5
  This document will describe, at a high level, how CRuby's compilation of Prism's AST works.
6
6
 
data/docs/design.md CHANGED
@@ -18,11 +18,11 @@ The templated files contain all of the code required to allocate and initialize
18
18
 
19
19
  In order to provide the best possible error tolerance, the parser is hand-written. It is structured using Pratt parsing, a technique developed by Vaughan Pratt back in the 1970s. Below are a bunch of links to articles and papers that explain Pratt parsing in more detail.
20
20
 
21
- * https://web.archive.org/web/20151223215421/http://hall.org.ua/halls/wizzard/pdf/Vaughan.Pratt.TDOP.pdf
21
+ * https://github.com/tdop/tdop.github.io/raw/master/original.pdf
22
22
  * https://tdop.github.io/
23
23
  * https://journal.stuffwithstuff.com/2011/03/19/pratt-parsers-expression-parsing-made-easy/
24
24
  * https://matklad.github.io/2020/04/13/simple-but-powerful-pratt-parsing.html
25
- * https://chidiwilliams.com/post/on-recursive-descent-and-pratt-parsing/
25
+ * https://chidiwilliams.com/posts/on-recursive-descent-and-pratt-parsing
26
26
 
27
27
  You can find most of the functions that correspond to constructs in the Pratt parsing algorithm in `prism.c`. As a couple of examples:
28
28
 
@@ -20,5 +20,5 @@ Prism::Translation::ParserCurrent.parse("puts 'Hello World!'")
20
20
 
21
21
  All the parsers are autoloaded, so you don't have to worry about requiring them yourself.
22
22
 
23
- If you also need to parse Ruby versions below 3.3 (which `prism` has no support for), check out
23
+ If you also need to parse Ruby versions below 3.3 (for which the `prism` translation layer does not have explicit support), check out
24
24
  [this guide](https://github.com/whitequark/parser/blob/master/doc/PRISM_TRANSLATION.md) from the `parser` gem on how to use both in conjunction.
data/docs/releasing.md CHANGED
@@ -40,14 +40,15 @@ ruby -pi -e 'gsub(/^ruby-prism-sys = \{ version = ".+?"/, %Q{ruby-prism-sys = \{
40
40
  * Update the `Gemfile.lock` file:
41
41
 
42
42
  ```sh
43
- chruby ruby-3.5.0-dev
43
+ chruby ruby-4.0.0-dev
44
44
  bundle install
45
45
  ```
46
46
 
47
47
  * Update the version-specific lockfiles:
48
48
 
49
49
  ```sh
50
- bin/prism bundle install
50
+ for VERSION in "2.7" "3.0" "3.1" "3.2" "3.3" "3.4" "4.0"; do docker run -it --rm -v "$PWD":/usr/src/app -w /usr/src/app -e BUNDLE_GEMFILE="gemfiles/$VERSION/Gemfile" "ruby:$VERSION" bundle update; done
51
+ chruby ruby-4.1.0-dev && BUNDLE_GEMFILE=gemfiles/4.1/Gemfile bundle install
51
52
  ```
52
53
 
53
54
  * Update the cargo lockfiles:
@@ -71,26 +72,4 @@ git push
71
72
  ## Publishing
72
73
 
73
74
  * Update the GitHub release page with a copy of the latest entry in the `CHANGELOG.md` file.
74
- * Publish the gem to [rubygems.org](rubygems.org). Note that you must have access to the `prism` gem to do this.
75
-
76
- ```sh
77
- bundle exec rake release
78
- ```
79
-
80
- * Generate the `wasm` artifact (or download it from GitHub actions and put it in `javascript/src/prism.wasm`).
81
-
82
- ```sh
83
- make wasm
84
- ```
85
-
86
- * Publish the JavaScript package to [npmjs.com](npmjs.com). Note that you must have access to the `@ruby/prism` package to do this.
87
-
88
- ```sh
89
- npm publish
90
- ```
91
-
92
- * Publish the rust crate to [crates.io](crates.io). Note that you must have access to the `ruby-prism-sys` and `ruby-prism` crates to do this.
93
-
94
- ```sh
95
- bundle exec rake cargo:publish:real
96
- ```
75
+ * Push a new tag to the GitHub repository, following the `vX.Y.Z` format.
data/docs/ruby_api.md CHANGED
@@ -36,6 +36,7 @@ Once you have nodes in hand coming out of a parse result, there are a number of
36
36
  * `#accept(visitor)` - a method that will immediately call `visit_*` to specialize for the node type
37
37
  * `#child_nodes` - a positional array of the child nodes of the node, with `nil` values for any missing children
38
38
  * `#compact_child_nodes` - a positional array of the child nodes of the node with no `nil` values
39
+ * `#each_child_node` - with a block given yields all child nodes, without a block return an enumerator containing all child nodes
39
40
  * `#copy(**keys)` - a method that allows creating a shallow copy of the node with the given keys overridden
40
41
  * `#deconstruct`/`#deconstruct_keys(keys)` - the pattern matching interface for nodes
41
42
  * `#inspect` - a string representation that looks like the syntax tree of the node
data/ext/prism/api_node.c CHANGED
@@ -1789,7 +1789,7 @@ pm_ast_new(const pm_parser_t *parser, const pm_node_t *node, rb_encoding *encodi
1789
1789
  #line 190 "prism/templates/ext/prism/api_node.c.erb"
1790
1790
  case PM_CALL_NODE: {
1791
1791
  pm_call_node_t *cast = (pm_call_node_t *) node;
1792
- VALUE argv[12];
1792
+ VALUE argv[13];
1793
1793
 
1794
1794
  // source
1795
1795
  argv[0] = source;
@@ -1832,11 +1832,15 @@ pm_ast_new(const pm_parser_t *parser, const pm_node_t *node, rb_encoding *encodi
1832
1832
  #line 243 "prism/templates/ext/prism/api_node.c.erb"
1833
1833
  argv[10] = cast->closing_loc.start == NULL ? Qnil : pm_location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source, freeze);
1834
1834
 
1835
+ // equal_loc
1836
+ #line 243 "prism/templates/ext/prism/api_node.c.erb"
1837
+ argv[11] = cast->equal_loc.start == NULL ? Qnil : pm_location_new(parser, cast->equal_loc.start, cast->equal_loc.end, source, freeze);
1838
+
1835
1839
  // block
1836
1840
  #line 213 "prism/templates/ext/prism/api_node.c.erb"
1837
- argv[11] = rb_ary_pop(value_stack);
1841
+ argv[12] = rb_ary_pop(value_stack);
1838
1842
 
1839
- VALUE value = rb_class_new_instance(12, argv, rb_cPrismCallNode);
1843
+ VALUE value = rb_class_new_instance(13, argv, rb_cPrismCallNode);
1840
1844
  if (freeze) rb_obj_freeze(value);
1841
1845
 
1842
1846
  rb_ary_push(value_stack, value);
data/ext/prism/extconf.rb CHANGED
@@ -37,7 +37,7 @@ end
37
37
  def generate_templates
38
38
  Dir.chdir(File.expand_path("../..", __dir__)) do
39
39
  if !File.exist?("include/prism/ast.h") && Dir.exist?(".git")
40
- system("templates/template.rb", exception: true)
40
+ system(RbConfig.ruby, "templates/template.rb", exception: true)
41
41
  end
42
42
  end
43
43
  end
@@ -25,6 +25,7 @@ VALUE rb_cPrismLexResult;
25
25
  VALUE rb_cPrismParseLexResult;
26
26
  VALUE rb_cPrismStringQuery;
27
27
  VALUE rb_cPrismScope;
28
+ VALUE rb_cPrismCurrentVersionError;
28
29
 
29
30
  VALUE rb_cPrismDebugEncoding;
30
31
 
@@ -199,7 +200,12 @@ build_options_i(VALUE key, VALUE value, VALUE argument) {
199
200
  if (!NIL_P(value)) {
200
201
  const char *version = check_string(value);
201
202
 
202
- if (!pm_options_version_set(options, version, RSTRING_LEN(value))) {
203
+ if (RSTRING_LEN(value) == 7 && strncmp(version, "current", 7) == 0) {
204
+ const char *current_version = RSTRING_PTR(rb_const_get(rb_cObject, rb_intern("RUBY_VERSION")));
205
+ if (!pm_options_version_set(options, current_version, 3)) {
206
+ rb_exc_raise(rb_exc_new_cstr(rb_cPrismCurrentVersionError, current_version));
207
+ }
208
+ } else if (!pm_options_version_set(options, version, RSTRING_LEN(value))) {
203
209
  rb_raise(rb_eArgError, "invalid version: %" PRIsVALUE, value);
204
210
  }
205
211
  }
@@ -888,7 +894,7 @@ parse_input(pm_string_t *input, const pm_options_t *options) {
888
894
  * version of Ruby syntax (which you can trigger with `nil` or
889
895
  * `"latest"`). You may also restrict the syntax to a specific version of
890
896
  * Ruby, e.g., with `"3.3.0"`. To parse with the same syntax version that
891
- * the current Ruby is running use `version: RUBY_VERSION`. Raises
897
+ * the current Ruby is running use `version: "current"`. Raises
892
898
  * ArgumentError if the version is not currently supported by Prism.
893
899
  */
894
900
  static VALUE
@@ -1364,6 +1370,8 @@ Init_prism(void) {
1364
1370
  rb_cPrismStringQuery = rb_define_class_under(rb_cPrism, "StringQuery", rb_cObject);
1365
1371
  rb_cPrismScope = rb_define_class_under(rb_cPrism, "Scope", rb_cObject);
1366
1372
 
1373
+ rb_cPrismCurrentVersionError = rb_const_get(rb_cPrism, rb_intern("CurrentVersionError"));
1374
+
1367
1375
  // Intern all of the IDs eagerly that we support so that we don't have to do
1368
1376
  // it every time we parse.
1369
1377
  rb_id_option_command_line = rb_intern_const("command_line");
@@ -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 "1.5.1"
4
+ #define EXPECTED_PRISM_VERSION "1.8.0"
5
5
 
6
6
  #include <ruby.h>
7
7
  #include <ruby/encoding.h>