prism 1.3.0 → 1.5.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 (87) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +46 -1
  3. data/Makefile +2 -1
  4. data/README.md +1 -0
  5. data/config.yml +273 -37
  6. data/docs/parser_translation.md +8 -23
  7. data/docs/releasing.md +1 -1
  8. data/docs/ripper_translation.md +1 -1
  9. data/docs/ruby_api.md +1 -1
  10. data/ext/prism/api_node.c +1816 -1303
  11. data/ext/prism/extension.c +244 -110
  12. data/ext/prism/extension.h +4 -4
  13. data/include/prism/ast.h +291 -49
  14. data/include/prism/defines.h +4 -1
  15. data/include/prism/diagnostic.h +4 -0
  16. data/include/prism/options.h +89 -3
  17. data/include/prism/regexp.h +2 -2
  18. data/include/prism/util/pm_buffer.h +18 -0
  19. data/include/prism/util/pm_integer.h +4 -0
  20. data/include/prism/util/pm_list.h +6 -0
  21. data/include/prism/util/pm_string.h +12 -2
  22. data/include/prism/version.h +2 -2
  23. data/include/prism.h +41 -16
  24. data/lib/prism/compiler.rb +456 -151
  25. data/lib/prism/desugar_compiler.rb +1 -0
  26. data/lib/prism/dispatcher.rb +16 -0
  27. data/lib/prism/dot_visitor.rb +21 -1
  28. data/lib/prism/dsl.rb +13 -2
  29. data/lib/prism/ffi.rb +62 -34
  30. data/lib/prism/inspect_visitor.rb +5 -1
  31. data/lib/prism/lex_compat.rb +1 -0
  32. data/lib/prism/mutation_compiler.rb +3 -0
  33. data/lib/prism/node.rb +554 -345
  34. data/lib/prism/node_ext.rb +4 -1
  35. data/lib/prism/pack.rb +2 -0
  36. data/lib/prism/parse_result/comments.rb +1 -0
  37. data/lib/prism/parse_result/errors.rb +1 -0
  38. data/lib/prism/parse_result/newlines.rb +2 -1
  39. data/lib/prism/parse_result.rb +53 -0
  40. data/lib/prism/pattern.rb +1 -0
  41. data/lib/prism/polyfill/append_as_bytes.rb +15 -0
  42. data/lib/prism/polyfill/scan_byte.rb +14 -0
  43. data/lib/prism/polyfill/warn.rb +42 -0
  44. data/lib/prism/reflection.rb +5 -2
  45. data/lib/prism/relocation.rb +1 -0
  46. data/lib/prism/serialize.rb +1275 -783
  47. data/lib/prism/string_query.rb +1 -0
  48. data/lib/prism/translation/parser/builder.rb +62 -0
  49. data/lib/prism/translation/parser/compiler.rb +230 -152
  50. data/lib/prism/translation/parser/lexer.rb +446 -64
  51. data/lib/prism/translation/parser.rb +64 -4
  52. data/lib/prism/translation/parser33.rb +1 -0
  53. data/lib/prism/translation/parser34.rb +1 -0
  54. data/lib/prism/translation/parser35.rb +13 -0
  55. data/lib/prism/translation/parser_current.rb +24 -0
  56. data/lib/prism/translation/ripper/sexp.rb +1 -0
  57. data/lib/prism/translation/ripper.rb +30 -4
  58. data/lib/prism/translation/ruby_parser.rb +291 -7
  59. data/lib/prism/translation.rb +3 -0
  60. data/lib/prism/visitor.rb +457 -152
  61. data/lib/prism.rb +5 -3
  62. data/prism.gemspec +9 -1
  63. data/rbi/prism/dsl.rbi +9 -6
  64. data/rbi/prism/node.rbi +43 -16
  65. data/rbi/prism/parse_result.rbi +17 -0
  66. data/rbi/prism/translation/parser35.rbi +6 -0
  67. data/rbi/prism.rbi +39 -36
  68. data/sig/prism/dispatcher.rbs +3 -0
  69. data/sig/prism/dsl.rbs +7 -5
  70. data/sig/prism/node.rbs +461 -37
  71. data/sig/prism/node_ext.rbs +84 -17
  72. data/sig/prism/parse_result/comments.rbs +38 -0
  73. data/sig/prism/parse_result.rbs +14 -0
  74. data/sig/prism/reflection.rbs +1 -1
  75. data/sig/prism/serialize.rbs +4 -2
  76. data/sig/prism.rbs +22 -1
  77. data/src/diagnostic.c +9 -3
  78. data/src/node.c +23 -0
  79. data/src/options.c +33 -2
  80. data/src/prettyprint.c +32 -0
  81. data/src/prism.c +620 -242
  82. data/src/serialize.c +8 -0
  83. data/src/token_type.c +36 -34
  84. data/src/util/pm_buffer.c +40 -0
  85. data/src/util/pm_constant_pool.c +6 -2
  86. data/src/util/pm_strncasecmp.c +13 -1
  87. metadata +11 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cc945a81285247ae139110607116e5ad0211e008f8e69d76002238755deca5dc
4
- data.tar.gz: 81703e9b86fd950af63fbea201f8cd9ddec3a3a330d24c80aba7461782bb347b
3
+ metadata.gz: 6d76af31baae33e36fc11994b9b755ce67a0795cdcd5e6dca245b9476991b161
4
+ data.tar.gz: 1505e09c2ed0e902ea7cb769531c1c4ce0b398fca78b8714fe1113204e9d348c
5
5
  SHA512:
6
- metadata.gz: 39fb25eec8d603cd26f31ce75281e3cf257f8f21451e6687eda11d14e090013651284b1f7b35612004b0603105883d0e1d8de1d82b192ce5238843e03203e9fa
7
- data.tar.gz: 4544a22d735276ca60cf3dd4e7b91ce64aa60539d555466d73d3eebb91502a0a357232bd1c0722232f3745481e554ba6ab2eb7a23f05a25e5d0c114f9077dc52
6
+ metadata.gz: 0df2dc7057692897f48ad99cdfe5f9d72a0ba6625dc0da1dc141ebadf36cf62405b1704997ffaa93318472b50a4919f4b3253708faf4f3bfcc093814f4f1a198
7
+ data.tar.gz: 2b3a959b7cf5b6103c15de81aeb99226045b27e090acc29a15247fe14b7492c97b6dc1b52c3ba584bfc4eb9fc18ba1744b78e6cf3b836c1e23b3025f5bdb960c
data/CHANGELOG.md CHANGED
@@ -6,6 +6,49 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [1.5.0] - 2025-09-12
10
+
11
+ ### Added
12
+
13
+ - Add `Prism::Translation::ParserCurrent`.
14
+ - Add `Integer::to_u32_digits` for the Rust API.
15
+ - Add `pm_comment_type_t` field for the Rust API.
16
+ - Support leading logical operators for CRuby 3.5+.
17
+
18
+ ### Changed
19
+
20
+ - Mark Prism as ractor-safe.
21
+ - Enforce a minimum version for the parser translation layer.
22
+ - Many fixes to the parser translation layer.
23
+ - Accept a newline after the `defined?` keyword.
24
+ - Reject `true && not true`.
25
+ - Make `it = it` assign nil to match parse.y behavior [Bug #21139].
26
+ - Some fixes to the ruby parser translation layer.
27
+ - Ensure call nodes have the correct ending location.
28
+ - Reject `foo && return bar`.
29
+
30
+ ## [1.4.0] - 2025-03-18
31
+
32
+ ### Added
33
+
34
+ - Support `3.5` as a version option.
35
+ - Many, many compatibility fixes for the parser translation layer.
36
+ - Handle escapes in named capture names.
37
+ - The `freeze` option is added to the various `Prism::` APIs to deeply freeze the AST.
38
+ - Properly support `it` for the parser and ruby_parser translation layers.
39
+ - Track the `then` keyword on `rescue` nodes.
40
+ - Add a `multiple_statements?` flag to parentheses nodes to support desired `defined?` behavior.
41
+
42
+ ### Changed
43
+
44
+ - The strings used in the AST are now frozen.
45
+ - Fixed handling escaped characters after control sequences in character literals.
46
+ - Fix reading off the end of an unterminated global variable.
47
+ - Raise a syntax error for defining `[]=` with endless method syntax.
48
+ - Increase value of `PRISM_DEPTH_MAXIMUM` to `10000`.
49
+ - Freeze `Prism::VERSION`.
50
+ - Fix up rescue modifier precedence.
51
+
9
52
  ## [1.3.0] - 2024-12-21
10
53
 
11
54
  ### Added
@@ -627,7 +670,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
627
670
 
628
671
  - 🎉 Initial release! 🎉
629
672
 
630
- [unreleased]: https://github.com/ruby/prism/compare/v1.3.0...HEAD
673
+ [unreleased]: https://github.com/ruby/prism/compare/v1.5.0...HEAD
674
+ [1.5.0]: https://github.com/ruby/prism/compare/v1.4.0...v1.5.0
675
+ [1.4.0]: https://github.com/ruby/prism/compare/v1.3.0...v1.4.0
631
676
  [1.3.0]: https://github.com/ruby/prism/compare/v1.2.0...v1.3.0
632
677
  [1.2.0]: https://github.com/ruby/prism/compare/v1.1.0...v1.2.0
633
678
  [1.1.0]: https://github.com/ruby/prism/compare/v1.0.0...v1.1.0
data/Makefile CHANGED
@@ -12,6 +12,7 @@ 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 -Wimplicit-fallthrough $(CFLAGS)
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)
15
16
  CC ?= cc
16
17
  AR ?= ar
17
18
  WASI_SDK_PATH := /opt/wasi-sdk
@@ -45,7 +46,7 @@ javascript/src/prism.wasm: Makefile $(SOURCES) $(HEADERS)
45
46
 
46
47
  java-wasm/src/test/resources/prism.wasm: Makefile $(SOURCES) $(HEADERS)
47
48
  $(ECHO) "building $@"
48
- $(Q) $(WASI_SDK_PATH)/bin/clang $(DEBUG_FLAGS) -DPRISM_EXPORT_SYMBOLS -D_WASI_EMULATED_MMAN -lwasi-emulated-mman $(CPPFLAGS) $(CFLAGS) -Wl,--export-all -Wl,--no-entry -mexec-model=reactor -lc++ -lc++abi -o $@ $(SOURCES)
49
+ $(Q) $(WASI_SDK_PATH)/bin/clang $(DEBUG_FLAGS) -DPRISM_EXCLUDE_PRETTYPRINT -DPRISM_EXPORT_SYMBOLS -D_WASI_EMULATED_MMAN -lwasi-emulated-mman $(CPPFLAGS) $(JAVA_WASM_CFLAGS) -Wl,--export-all -Wl,--no-entry -mexec-model=reactor -lc++ -lc++abi -o $@ $(SOURCES)
49
50
 
50
51
  build/shared/%.o: src/%.c Makefile $(HEADERS)
51
52
  $(ECHO) "compiling $@"
data/README.md CHANGED
@@ -139,3 +139,4 @@ Prism has been integrated into the majority of Ruby runtimes, many libraries, an
139
139
  ### Applications
140
140
 
141
141
  * [gem.sh](https://github.com/marcoroth/gem.sh/pull/96)
142
+ * [Sorbet](https://github.com/sorbet/sorbet)
data/config.yml CHANGED
@@ -101,6 +101,8 @@ errors:
101
101
  - EXPECT_FOR_DELIMITER
102
102
  - EXPECT_IDENT_REQ_PARAMETER
103
103
  - EXPECT_IN_DELIMITER
104
+ - EXPECT_LPAREN_AFTER_NOT_LPAREN
105
+ - EXPECT_LPAREN_AFTER_NOT_OTHER
104
106
  - EXPECT_LPAREN_REQ_PARAMETER
105
107
  - EXPECT_MESSAGE
106
108
  - EXPECT_RBRACKET
@@ -320,13 +322,42 @@ warnings:
320
322
  - UNUSED_LOCAL_VARIABLE
321
323
  - VOID_STATEMENT
322
324
  tokens:
325
+ # The order of the tokens at the beginning is important, because we use them
326
+ # for a lookup table.
323
327
  - name: EOF
324
328
  value: 1
325
329
  comment: final token in the file
326
- - name: MISSING
327
- comment: "a token that was expected but not found"
328
- - name: NOT_PROVIDED
329
- comment: "a token that was not present but it is okay"
330
+ - name: BRACE_RIGHT
331
+ comment: "}"
332
+ - name: COMMA
333
+ comment: ","
334
+ - name: EMBEXPR_END
335
+ comment: "}"
336
+ - name: KEYWORD_DO
337
+ comment: "do"
338
+ - name: KEYWORD_ELSE
339
+ comment: "else"
340
+ - name: KEYWORD_ELSIF
341
+ comment: "elsif"
342
+ - name: KEYWORD_END
343
+ comment: "end"
344
+ - name: KEYWORD_ENSURE
345
+ comment: "ensure"
346
+ - name: KEYWORD_IN
347
+ comment: "in"
348
+ - name: KEYWORD_RESCUE
349
+ comment: "rescue"
350
+ - name: KEYWORD_THEN
351
+ comment: "then"
352
+ - name: KEYWORD_WHEN
353
+ comment: "when"
354
+ - name: NEWLINE
355
+ comment: "a newline character outside of other tokens"
356
+ - name: PARENTHESIS_RIGHT
357
+ comment: ")"
358
+ - name: SEMICOLON
359
+ comment: ";"
360
+ # Tokens from here on are not used for lookup, and can be in any order.
330
361
  - name: AMPERSAND
331
362
  comment: "&"
332
363
  - name: AMPERSAND_AMPERSAND
@@ -349,8 +380,6 @@ tokens:
349
380
  comment: "!~"
350
381
  - name: BRACE_LEFT
351
382
  comment: "{"
352
- - name: BRACE_RIGHT
353
- comment: "}"
354
383
  - name: BRACKET_LEFT
355
384
  comment: "["
356
385
  - name: BRACKET_LEFT_ARRAY
@@ -373,8 +402,6 @@ tokens:
373
402
  comment: ":"
374
403
  - name: COLON_COLON
375
404
  comment: "::"
376
- - name: COMMA
377
- comment: ","
378
405
  - name: COMMENT
379
406
  comment: "a comment"
380
407
  - name: CONSTANT
@@ -393,8 +420,6 @@ tokens:
393
420
  comment: "a line inside of embedded documentation"
394
421
  - name: EMBEXPR_BEGIN
395
422
  comment: "#{"
396
- - name: EMBEXPR_END
397
- comment: "}"
398
423
  - name: EMBVAR
399
424
  comment: "#"
400
425
  - name: EQUAL
@@ -461,20 +486,10 @@ tokens:
461
486
  comment: "def"
462
487
  - name: KEYWORD_DEFINED
463
488
  comment: "defined?"
464
- - name: KEYWORD_DO
465
- comment: "do"
466
489
  - name: KEYWORD_DO_LOOP
467
490
  comment: "do keyword for a predicate in a while, until, or for loop"
468
- - name: KEYWORD_ELSE
469
- comment: "else"
470
- - name: KEYWORD_ELSIF
471
- comment: "elsif"
472
- - name: KEYWORD_END
473
- comment: "end"
474
491
  - name: KEYWORD_END_UPCASE
475
492
  comment: "END"
476
- - name: KEYWORD_ENSURE
477
- comment: "ensure"
478
493
  - name: KEYWORD_FALSE
479
494
  comment: "false"
480
495
  - name: KEYWORD_FOR
@@ -483,8 +498,6 @@ tokens:
483
498
  comment: "if"
484
499
  - name: KEYWORD_IF_MODIFIER
485
500
  comment: "if in the modifier form"
486
- - name: KEYWORD_IN
487
- comment: "in"
488
501
  - name: KEYWORD_MODULE
489
502
  comment: "module"
490
503
  - name: KEYWORD_NEXT
@@ -497,8 +510,6 @@ tokens:
497
510
  comment: "or"
498
511
  - name: KEYWORD_REDO
499
512
  comment: "redo"
500
- - name: KEYWORD_RESCUE
501
- comment: "rescue"
502
513
  - name: KEYWORD_RESCUE_MODIFIER
503
514
  comment: "rescue in the modifier form"
504
515
  - name: KEYWORD_RETRY
@@ -509,8 +520,6 @@ tokens:
509
520
  comment: "self"
510
521
  - name: KEYWORD_SUPER
511
522
  comment: "super"
512
- - name: KEYWORD_THEN
513
- comment: "then"
514
523
  - name: KEYWORD_TRUE
515
524
  comment: "true"
516
525
  - name: KEYWORD_UNDEF
@@ -523,8 +532,6 @@ tokens:
523
532
  comment: "until"
524
533
  - name: KEYWORD_UNTIL_MODIFIER
525
534
  comment: "until in the modifier form"
526
- - name: KEYWORD_WHEN
527
- comment: "when"
528
535
  - name: KEYWORD_WHILE
529
536
  comment: "while"
530
537
  - name: KEYWORD_WHILE_MODIFIER
@@ -561,16 +568,12 @@ tokens:
561
568
  comment: "-="
562
569
  - name: MINUS_GREATER
563
570
  comment: "->"
564
- - name: NEWLINE
565
- comment: "a newline character outside of other tokens"
566
571
  - name: NUMBERED_REFERENCE
567
572
  comment: "a numbered reference to a capture group in the previous regular expression match"
568
573
  - name: PARENTHESIS_LEFT
569
574
  comment: "("
570
575
  - name: PARENTHESIS_LEFT_PARENTHESES
571
576
  comment: "( for a parentheses node"
572
- - name: PARENTHESIS_RIGHT
573
- comment: ")"
574
577
  - name: PERCENT
575
578
  comment: "%"
576
579
  - name: PERCENT_EQUAL
@@ -603,8 +606,6 @@ tokens:
603
606
  comment: "the beginning of a regular expression"
604
607
  - name: REGEXP_END
605
608
  comment: "the end of a regular expression"
606
- - name: SEMICOLON
607
- comment: ";"
608
609
  - name: SLASH
609
610
  comment: "/"
610
611
  - name: SLASH_EQUAL
@@ -649,6 +650,10 @@ tokens:
649
650
  comment: "a separator between words in a list"
650
651
  - name: __END__
651
652
  comment: "marker for the point in the file at which the parser should stop"
653
+ - name: MISSING
654
+ comment: "a token that was expected but not found"
655
+ - name: NOT_PROVIDED
656
+ comment: "a token that was not present but it is okay"
652
657
  flags:
653
658
  - name: ArgumentsNodeFlags
654
659
  values:
@@ -719,6 +724,11 @@ flags:
719
724
  - name: REPEATED_PARAMETER
720
725
  comment: "a parameter name that has been repeated in the method signature"
721
726
  comment: Flags for parameter nodes.
727
+ - name: ParenthesesNodeFlags
728
+ values:
729
+ - name: MULTIPLE_STATEMENTS
730
+ comment: "parentheses that contain multiple potentially void statements"
731
+ comment: Flags for parentheses nodes.
722
732
  - name: RangeFlags
723
733
  values:
724
734
  - name: EXCLUDE_END
@@ -982,8 +992,19 @@ nodes:
982
992
  - name: constant
983
993
  type: node?
984
994
  kind:
985
- - ConstantReadNode
986
995
  - ConstantPathNode
996
+ - ConstantReadNode
997
+ comment: |
998
+ Represents the optional constant preceding the Array
999
+
1000
+ foo in Bar[]
1001
+ ^^^
1002
+
1003
+ foo in Bar[1, 2, 3]
1004
+ ^^^
1005
+
1006
+ foo in Bar::Baz[1, 2, 3]
1007
+ ^^^^^^^^
987
1008
  - name: requireds
988
1009
  type: node[]
989
1010
  kind: pattern expression
@@ -1823,6 +1844,11 @@ nodes:
1823
1844
  type: constant[]
1824
1845
  - name: class_keyword_loc
1825
1846
  type: location
1847
+ comment: |
1848
+ Represents the location of the `class` keyword.
1849
+
1850
+ class Foo end
1851
+ ^^^^^
1826
1852
  - name: constant_path
1827
1853
  type: node
1828
1854
  kind:
@@ -1831,18 +1857,43 @@ nodes:
1831
1857
  - on error: CallNode # class 0.X end
1832
1858
  - name: inheritance_operator_loc
1833
1859
  type: location?
1860
+ comment: |
1861
+ Represents the location of the `<` operator.
1862
+
1863
+ class Foo < Bar
1864
+ ^
1834
1865
  - name: superclass
1835
1866
  type: node?
1836
1867
  kind: non-void expression
1868
+ comment: |
1869
+ Represents the superclass of the class.
1870
+
1871
+ class Foo < Bar
1872
+ ^^^
1837
1873
  - name: body
1838
1874
  type: node?
1839
1875
  kind:
1840
1876
  - StatementsNode
1841
1877
  - BeginNode
1878
+ comment: |
1879
+ Represents the body of the class.
1880
+
1881
+ class Foo
1882
+ foo
1883
+ ^^^
1842
1884
  - name: end_keyword_loc
1843
1885
  type: location
1886
+ comment: |
1887
+ Represents the location of the `end` keyword.
1888
+
1889
+ class Foo end
1890
+ ^^^
1844
1891
  - name: name
1845
1892
  type: constant
1893
+ comment: |
1894
+ The name of the class.
1895
+
1896
+ class Foo end # name `:Foo`
1846
1897
  comment: |
1847
1898
  Represents a class declaration involving the `class` keyword.
1848
1899
 
@@ -2369,23 +2420,68 @@ nodes:
2369
2420
  - name: constant
2370
2421
  type: node?
2371
2422
  kind:
2372
- - ConstantReadNode
2373
2423
  - ConstantPathNode
2424
+ - ConstantReadNode
2425
+ comment: |
2426
+ Represents the optional constant preceding the pattern
2427
+
2428
+ foo in Foo(*bar, baz, *qux)
2429
+ ^^^
2374
2430
  - name: left
2375
2431
  type: node
2376
2432
  kind: SplatNode
2433
+ comment: |
2434
+ Represents the first wildcard node in the pattern.
2435
+
2436
+ foo in *bar, baz, *qux
2437
+ ^^^^
2438
+
2439
+ foo in Foo(*bar, baz, *qux)
2440
+ ^^^^
2377
2441
  - name: requireds
2378
2442
  type: node[]
2379
2443
  kind: pattern expression
2444
+ comment: |
2445
+ Represents the nodes in between the wildcards.
2446
+
2447
+ foo in *bar, baz, *qux
2448
+ ^^^
2449
+
2450
+ foo in Foo(*bar, baz, 1, *qux)
2451
+ ^^^^^^
2380
2452
  - name: right
2381
2453
  type: node
2382
2454
  kind:
2383
2455
  - SplatNode
2384
2456
  - on error: MissingNode
2457
+ comment: |
2458
+ Represents the second wildcard node in the pattern.
2459
+
2460
+ foo in *bar, baz, *qux
2461
+ ^^^^
2462
+
2463
+ foo in Foo(*bar, baz, *qux)
2464
+ ^^^^
2385
2465
  - name: opening_loc
2386
2466
  type: location?
2467
+ comment: |
2468
+ The location of the opening brace.
2469
+
2470
+ foo in [*bar, baz, *qux]
2471
+ ^
2472
+
2473
+ foo in Foo(*bar, baz, *qux)
2474
+ ^
2387
2475
  - name: closing_loc
2388
2476
  type: location?
2477
+ comment: |
2478
+ The location of the closing brace.
2479
+
2480
+ foo in [*bar, baz, *qux]
2481
+ ^
2482
+
2483
+ foo in Foo(*bar, baz, *qux)
2484
+ ^
2389
2485
  comment: |
2390
2486
  Represents a find pattern in pattern matching.
2391
2487
 
@@ -2397,6 +2493,9 @@ nodes:
2397
2493
 
2398
2494
  foo in Foo(*bar, baz, *qux)
2399
2495
  ^^^^^^^^^^^^^^^^^^^^
2496
+
2497
+ foo => *bar, baz, *qux
2498
+ ^^^^^^^^^^^^^^^
2400
2499
  - name: FlipFlopNode
2401
2500
  flags: RangeFlags
2402
2501
  fields:
@@ -2674,20 +2773,60 @@ nodes:
2674
2773
  - name: constant
2675
2774
  type: node?
2676
2775
  kind:
2677
- - ConstantReadNode
2678
2776
  - ConstantPathNode
2777
+ - ConstantReadNode
2778
+ comment: |
2779
+ Represents the optional constant preceding the Hash.
2780
+
2781
+ foo => Bar[a: 1, b: 2]
2782
+ ^^^
2783
+
2784
+ foo => Bar::Baz[a: 1, b: 2]
2785
+ ^^^^^^^^
2679
2786
  - name: elements
2680
2787
  type: node[]
2681
2788
  kind: AssocNode
2789
+ comment: |
2790
+ Represents the explicit named hash keys and values.
2791
+
2792
+ foo => { a: 1, b:, ** }
2793
+ ^^^^^^^^
2682
2794
  - name: rest
2683
2795
  type: node?
2684
2796
  kind:
2685
2797
  - AssocSplatNode
2686
2798
  - NoKeywordsParameterNode
2799
+ comment: |
2800
+ Represents the rest of the Hash keys and values. This can be named, unnamed, or explicitly forbidden via `**nil`, this last one results in a `NoKeywordsParameterNode`.
2801
+
2802
+ foo => { a: 1, b:, **c }
2803
+ ^^^
2804
+
2805
+ foo => { a: 1, b:, ** }
2806
+ ^^
2807
+
2808
+ foo => { a: 1, b:, **nil }
2809
+ ^^^^^
2687
2810
  - name: opening_loc
2688
2811
  type: location?
2812
+ comment: |
2813
+ The location of the opening brace.
2814
+
2815
+ foo => { a: 1 }
2816
+ ^
2817
+
2818
+ foo => Bar[a: 1]
2819
+ ^
2689
2820
  - name: closing_loc
2690
2821
  type: location?
2822
+ comment: |
2823
+ The location of the closing brace.
2824
+
2825
+ foo => { a: 1 }
2826
+ ^
2827
+
2828
+ foo => Bar[a: 1]
2829
+ ^
2691
2830
  comment: |
2692
2831
  Represents a hash pattern in pattern matching.
2693
2832
 
@@ -2696,6 +2835,12 @@ nodes:
2696
2835
 
2697
2836
  foo => { a: 1, b: 2, **c }
2698
2837
  ^^^^^^^^^^^^^^^^^^^
2838
+
2839
+ foo => Bar[a: 1, b: 2]
2840
+ ^^^^^^^^^^^^^^^
2841
+
2842
+ foo in { a: 1, b: 2 }
2843
+ ^^^^^^^^^^^^^^
2699
2844
  - name: IfNode
2700
2845
  fields:
2701
2846
  - name: if_keyword_loc
@@ -3140,6 +3285,7 @@ nodes:
3140
3285
  - EmbeddedStatementsNode
3141
3286
  - EmbeddedVariableNode
3142
3287
  - InterpolatedStringNode # `"a" "#{b}"`
3288
+ - on error: XStringNode # `<<`FOO` "bar"
3143
3289
  - name: closing_loc
3144
3290
  type: location?
3145
3291
  newline: parts
@@ -3347,6 +3493,9 @@ nodes:
3347
3493
 
3348
3494
  foo, bar = baz
3349
3495
  ^^^ ^^^
3496
+
3497
+ foo => baz
3498
+ ^^^
3350
3499
  - name: LocalVariableWriteNode
3351
3500
  fields:
3352
3501
  - name: name
@@ -3437,11 +3586,65 @@ nodes:
3437
3586
  - name: value
3438
3587
  type: node
3439
3588
  kind: non-void expression
3589
+ comment: |
3590
+ Represents the left-hand side of the operator.
3591
+
3592
+ foo => bar
3593
+ ^^^
3440
3594
  - name: pattern
3441
3595
  type: node
3442
3596
  kind: pattern expression
3597
+ comment: |
3598
+ Represents the right-hand side of the operator. The type of the node depends on the expression.
3599
+
3600
+ Anything that looks like a local variable name (including `_`) will result in a `LocalVariableTargetNode`.
3601
+
3602
+ foo => a # This is equivalent to writing `a = foo`
3603
+ ^
3604
+
3605
+ Using an explicit `Array` or combining expressions with `,` will result in a `ArrayPatternNode`. This can be preceded by a constant.
3606
+
3607
+ foo => [a]
3608
+ ^^^
3609
+
3610
+ foo => a, b
3611
+ ^^^^
3612
+
3613
+ foo => Bar[a, b]
3614
+ ^^^^^^^^^
3615
+
3616
+ If the array pattern contains at least two wildcard matches, a `FindPatternNode` is created instead.
3617
+
3618
+ foo => *, 1, *a
3619
+ ^^^^^
3620
+
3621
+ Using an explicit `Hash` or a constant with square brackets and hash keys in the square brackets will result in a `HashPatternNode`.
3622
+
3623
+ foo => { a: 1, b: }
3624
+
3625
+ foo => Bar[a: 1, b:]
3626
+
3627
+ foo => Bar[**]
3628
+
3629
+ To use any variable that needs run time evaluation, pinning is required. This results in a `PinnedVariableNode`
3630
+
3631
+ foo => ^a
3632
+ ^^
3633
+
3634
+ Similar, any expression can be used with pinning. This results in a `PinnedExpressionNode`.
3635
+
3636
+ foo => ^(a + 1)
3637
+
3638
+ Anything else will result in the regular node for that expression, for example a `ConstantReadNode`.
3639
+
3640
+ foo => CONST
3443
3641
  - name: operator_loc
3444
3642
  type: location
3643
+ comment: |
3644
+ The location of the operator.
3645
+
3646
+ foo => bar
3647
+ ^^
3445
3648
  comment: |
3446
3649
  Represents the use of the `=>` operator.
3447
3650
 
@@ -3851,6 +4054,7 @@ nodes:
3851
4054
  ^^^^^^^
3852
4055
  end
3853
4056
  - name: ParenthesesNode
4057
+ flags: ParenthesesNodeFlags
3854
4058
  fields:
3855
4059
  - name: body
3856
4060
  type: node?
@@ -3870,12 +4074,32 @@ nodes:
3870
4074
  - name: expression
3871
4075
  type: node
3872
4076
  kind: non-void expression
4077
+ comment: |
4078
+ The expression used in the pinned expression
4079
+
4080
+ foo in ^(bar)
4081
+ ^^^
3873
4082
  - name: operator_loc
3874
4083
  type: location
4084
+ comment: |
4085
+ The location of the `^` operator
4086
+
4087
+ foo in ^(bar)
4088
+ ^
3875
4089
  - name: lparen_loc
3876
4090
  type: location
4091
+ comment: |
4092
+ The location of the opening parenthesis.
4093
+
4094
+ foo in ^(bar)
4095
+ ^
3877
4096
  - name: rparen_loc
3878
4097
  type: location
4098
+ comment: |
4099
+ The location of the closing parenthesis.
4100
+
4101
+ foo in ^(bar)
4102
+ ^
3879
4103
  comment: |
3880
4104
  Represents the use of the `^` operator for pinning an expression in a pattern matching expression.
3881
4105
 
@@ -3894,8 +4118,18 @@ nodes:
3894
4118
  - NumberedReferenceReadNode # foo in ^$1
3895
4119
  - ItLocalVariableReadNode # proc { 1 in ^it }
3896
4120
  - on error: MissingNode # foo in ^Bar
4121
+ comment: |
4122
+ The variable used in the pinned expression
4123
+
4124
+ foo in ^bar
4125
+ ^^^
3897
4126
  - name: operator_loc
3898
4127
  type: location
4128
+ comment: |
4129
+ The location of the `^` operator
4130
+
4131
+ foo in ^bar
4132
+ ^
3899
4133
  comment: |
3900
4134
  Represents the use of the `^` operator for pinning a variable in a pattern matching expression.
3901
4135
 
@@ -4084,6 +4318,8 @@ nodes:
4084
4318
  - on error: BackReferenceReadNode # => begin; rescue => $&; end
4085
4319
  - on error: NumberedReferenceReadNode # => begin; rescue => $1; end
4086
4320
  - on error: MissingNode # begin; rescue =>; end
4321
+ - name: then_keyword_loc
4322
+ type: location?
4087
4323
  - name: statements
4088
4324
  type: node?
4089
4325
  kind: StatementsNode
@@ -6,34 +6,19 @@ Prism ships with the ability to translate its syntax tree into the syntax tree u
6
6
 
7
7
  The `parser` gem provides multiple parsers to support different versions of the Ruby grammar. This includes all of the Ruby versions going back to 1.8, as well as third-party parsers like MacRuby and RubyMotion. The `prism` gem provides another parser that uses the `prism` parser to build the syntax tree.
8
8
 
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.
9
+ You can use the `prism` parser like you would any other. After requiring `prism`, you should be able to call any of the regular `Parser::Base` APIs that you would normally use.
10
10
 
11
11
  ```ruby
12
12
  require "prism"
13
13
 
14
- Prism::Translation::Parser.parse_file("path/to/file.rb")
15
- ```
16
-
17
- ### RuboCop
18
-
19
- Prism as a parser engine is directly supported since RuboCop 1.62. The class used for parsing is `Prism::Translation::Parser`.
20
-
21
- First, specify `prism` in your Gemfile:
22
-
23
- ```ruby
24
- gem "prism"
25
- ```
26
-
27
- To use Prism with RuboCop, specify `ParserEngine` and `TargetRubyVersion` in your RuboCop configuration file:
14
+ # Same as `Parser::Ruby34`
15
+ Prism::Translation::Parser34.parse_file("path/to/file.rb")
28
16
 
29
- ```yaml
30
- AllCops:
31
- ParserEngine: parser_prism
32
- TargetRubyVersion: 3.3
17
+ # Same as `Parser::CurrentRuby`
18
+ Prism::Translation::ParserCurrent.parse("puts 'Hello World!'")
33
19
  ```
34
20
 
35
- The default value for `ParserEngine` is `parser_whitequark`, which indicates the Parser gem. You need to explicitly switch it to `parser_prism` to indicate Prism. Additionally, the value for `TargetRubyVersion` must be specified as `3.3` or higher, as Prism supports parsing versions of Ruby 3.3 and higher.
36
- The parser class is determined by the combination of values for `ParserEngine` and `TargetRubyVersion`. For example, if `TargetRubyVersion: 3.3`, parsing is performed by `Prism::Translation::Parser33`, and for `TargetRubyVersion 3.4`, parsing is performed by `Prism::Translation::Parser34`.
21
+ All the parsers are autoloaded, so you don't have to worry about requiring them yourself.
37
22
 
38
- For further information, please refer to the RuboCop documentation:
39
- https://docs.rubocop.org/rubocop/configuration.html#setting-the-parser-engine
23
+ If you also need to parse Ruby versions below 3.3 (which `prism` has no support for), check out
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.