prism 1.4.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +23 -1
- data/Makefile +2 -1
- data/README.md +1 -0
- data/config.yml +264 -37
- data/docs/parser_translation.md +8 -23
- data/docs/ripper_translation.md +1 -1
- data/ext/prism/api_node.c +2 -0
- data/ext/prism/extension.c +14 -1
- data/ext/prism/extension.h +1 -1
- data/include/prism/ast.h +275 -49
- data/include/prism/diagnostic.h +4 -0
- data/include/prism/options.h +43 -3
- data/include/prism/regexp.h +2 -2
- data/include/prism/util/pm_buffer.h +8 -0
- data/include/prism/util/pm_integer.h +4 -0
- data/include/prism/util/pm_list.h +6 -0
- data/include/prism/util/pm_string.h +12 -2
- data/include/prism/version.h +2 -2
- data/include/prism.h +39 -14
- data/lib/prism/compiler.rb +456 -151
- data/lib/prism/desugar_compiler.rb +1 -0
- data/lib/prism/dispatcher.rb +16 -0
- data/lib/prism/dot_visitor.rb +5 -1
- data/lib/prism/dsl.rb +3 -0
- data/lib/prism/ffi.rb +17 -7
- data/lib/prism/inspect_visitor.rb +3 -0
- data/lib/prism/lex_compat.rb +1 -0
- data/lib/prism/mutation_compiler.rb +3 -0
- data/lib/prism/node.rb +506 -335
- data/lib/prism/node_ext.rb +4 -1
- data/lib/prism/pack.rb +2 -0
- data/lib/prism/parse_result/comments.rb +1 -0
- data/lib/prism/parse_result/errors.rb +1 -0
- data/lib/prism/parse_result/newlines.rb +1 -0
- data/lib/prism/parse_result.rb +1 -0
- data/lib/prism/pattern.rb +1 -0
- data/lib/prism/polyfill/scan_byte.rb +14 -0
- data/lib/prism/polyfill/warn.rb +42 -0
- data/lib/prism/reflection.rb +3 -0
- data/lib/prism/relocation.rb +1 -0
- data/lib/prism/serialize.rb +24 -19
- data/lib/prism/string_query.rb +1 -0
- data/lib/prism/translation/parser/builder.rb +1 -0
- data/lib/prism/translation/parser/compiler.rb +47 -25
- data/lib/prism/translation/parser/lexer.rb +29 -21
- data/lib/prism/translation/parser.rb +13 -1
- data/lib/prism/translation/parser33.rb +1 -0
- data/lib/prism/translation/parser34.rb +1 -0
- data/lib/prism/translation/parser35.rb +1 -0
- data/lib/prism/translation/parser_current.rb +24 -0
- data/lib/prism/translation/ripper/sexp.rb +1 -0
- data/lib/prism/translation/ripper.rb +17 -1
- data/lib/prism/translation/ruby_parser.rb +286 -3
- data/lib/prism/translation.rb +2 -0
- data/lib/prism/visitor.rb +457 -152
- data/lib/prism.rb +2 -0
- data/prism.gemspec +5 -1
- data/rbi/prism/dsl.rbi +3 -3
- data/rbi/prism/node.rbi +21 -9
- data/sig/prism/dispatcher.rbs +3 -0
- data/sig/prism/dsl.rbs +3 -3
- data/sig/prism/node.rbs +444 -30
- data/sig/prism/node_ext.rbs +84 -17
- data/sig/prism/parse_result/comments.rbs +38 -0
- data/sig/prism/parse_result.rbs +4 -0
- data/sig/prism/reflection.rbs +1 -1
- data/src/diagnostic.c +7 -1
- data/src/node.c +2 -0
- data/src/options.c +2 -2
- data/src/prettyprint.c +2 -0
- data/src/prism.c +252 -130
- data/src/serialize.c +2 -0
- data/src/token_type.c +36 -34
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6d76af31baae33e36fc11994b9b755ce67a0795cdcd5e6dca245b9476991b161
|
4
|
+
data.tar.gz: 1505e09c2ed0e902ea7cb769531c1c4ce0b398fca78b8714fe1113204e9d348c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0df2dc7057692897f48ad99cdfe5f9d72a0ba6625dc0da1dc141ebadf36cf62405b1704997ffaa93318472b50a4919f4b3253708faf4f3bfcc093814f4f1a198
|
7
|
+
data.tar.gz: 2b3a959b7cf5b6103c15de81aeb99226045b27e090acc29a15247fe14b7492c97b6dc1b52c3ba584bfc4eb9fc18ba1744b78e6cf3b836c1e23b3025f5bdb960c
|
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,27 @@ 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
|
+
|
9
30
|
## [1.4.0] - 2025-03-18
|
10
31
|
|
11
32
|
### Added
|
@@ -649,7 +670,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
|
|
649
670
|
|
650
671
|
- 🎉 Initial release! 🎉
|
651
672
|
|
652
|
-
[unreleased]: https://github.com/ruby/prism/compare/v1.
|
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
|
653
675
|
[1.4.0]: https://github.com/ruby/prism/compare/v1.3.0...v1.4.0
|
654
676
|
[1.3.0]: https://github.com/ruby/prism/compare/v1.2.0...v1.3.0
|
655
677
|
[1.2.0]: https://github.com/ruby/prism/compare/v1.1.0...v1.2.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) $(
|
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
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:
|
327
|
-
comment: "
|
328
|
-
- name:
|
329
|
-
comment: "
|
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:
|
@@ -987,8 +992,19 @@ nodes:
|
|
987
992
|
- name: constant
|
988
993
|
type: node?
|
989
994
|
kind:
|
990
|
-
- ConstantReadNode
|
991
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
|
+
^^^^^^^^
|
992
1008
|
- name: requireds
|
993
1009
|
type: node[]
|
994
1010
|
kind: pattern expression
|
@@ -1828,6 +1844,11 @@ nodes:
|
|
1828
1844
|
type: constant[]
|
1829
1845
|
- name: class_keyword_loc
|
1830
1846
|
type: location
|
1847
|
+
comment: |
|
1848
|
+
Represents the location of the `class` keyword.
|
1849
|
+
|
1850
|
+
class Foo end
|
1851
|
+
^^^^^
|
1831
1852
|
- name: constant_path
|
1832
1853
|
type: node
|
1833
1854
|
kind:
|
@@ -1836,18 +1857,43 @@ nodes:
|
|
1836
1857
|
- on error: CallNode # class 0.X end
|
1837
1858
|
- name: inheritance_operator_loc
|
1838
1859
|
type: location?
|
1860
|
+
comment: |
|
1861
|
+
Represents the location of the `<` operator.
|
1862
|
+
|
1863
|
+
class Foo < Bar
|
1864
|
+
^
|
1839
1865
|
- name: superclass
|
1840
1866
|
type: node?
|
1841
1867
|
kind: non-void expression
|
1868
|
+
comment: |
|
1869
|
+
Represents the superclass of the class.
|
1870
|
+
|
1871
|
+
class Foo < Bar
|
1872
|
+
^^^
|
1842
1873
|
- name: body
|
1843
1874
|
type: node?
|
1844
1875
|
kind:
|
1845
1876
|
- StatementsNode
|
1846
1877
|
- BeginNode
|
1878
|
+
comment: |
|
1879
|
+
Represents the body of the class.
|
1880
|
+
|
1881
|
+
class Foo
|
1882
|
+
foo
|
1883
|
+
^^^
|
1847
1884
|
- name: end_keyword_loc
|
1848
1885
|
type: location
|
1886
|
+
comment: |
|
1887
|
+
Represents the location of the `end` keyword.
|
1888
|
+
|
1889
|
+
class Foo end
|
1890
|
+
^^^
|
1849
1891
|
- name: name
|
1850
1892
|
type: constant
|
1893
|
+
comment: |
|
1894
|
+
The name of the class.
|
1895
|
+
|
1896
|
+
class Foo end # name `:Foo`
|
1851
1897
|
comment: |
|
1852
1898
|
Represents a class declaration involving the `class` keyword.
|
1853
1899
|
|
@@ -2374,23 +2420,68 @@ nodes:
|
|
2374
2420
|
- name: constant
|
2375
2421
|
type: node?
|
2376
2422
|
kind:
|
2377
|
-
- ConstantReadNode
|
2378
2423
|
- ConstantPathNode
|
2424
|
+
- ConstantReadNode
|
2425
|
+
comment: |
|
2426
|
+
Represents the optional constant preceding the pattern
|
2427
|
+
|
2428
|
+
foo in Foo(*bar, baz, *qux)
|
2429
|
+
^^^
|
2379
2430
|
- name: left
|
2380
2431
|
type: node
|
2381
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
|
+
^^^^
|
2382
2441
|
- name: requireds
|
2383
2442
|
type: node[]
|
2384
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
|
+
^^^^^^
|
2385
2452
|
- name: right
|
2386
2453
|
type: node
|
2387
2454
|
kind:
|
2388
2455
|
- SplatNode
|
2389
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
|
+
^^^^
|
2390
2465
|
- name: opening_loc
|
2391
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
|
+
^
|
2392
2475
|
- name: closing_loc
|
2393
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
|
+
^
|
2394
2485
|
comment: |
|
2395
2486
|
Represents a find pattern in pattern matching.
|
2396
2487
|
|
@@ -2402,6 +2493,9 @@ nodes:
|
|
2402
2493
|
|
2403
2494
|
foo in Foo(*bar, baz, *qux)
|
2404
2495
|
^^^^^^^^^^^^^^^^^^^^
|
2496
|
+
|
2497
|
+
foo => *bar, baz, *qux
|
2498
|
+
^^^^^^^^^^^^^^^
|
2405
2499
|
- name: FlipFlopNode
|
2406
2500
|
flags: RangeFlags
|
2407
2501
|
fields:
|
@@ -2679,20 +2773,60 @@ nodes:
|
|
2679
2773
|
- name: constant
|
2680
2774
|
type: node?
|
2681
2775
|
kind:
|
2682
|
-
- ConstantReadNode
|
2683
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
|
+
^^^^^^^^
|
2684
2786
|
- name: elements
|
2685
2787
|
type: node[]
|
2686
2788
|
kind: AssocNode
|
2789
|
+
comment: |
|
2790
|
+
Represents the explicit named hash keys and values.
|
2791
|
+
|
2792
|
+
foo => { a: 1, b:, ** }
|
2793
|
+
^^^^^^^^
|
2687
2794
|
- name: rest
|
2688
2795
|
type: node?
|
2689
2796
|
kind:
|
2690
2797
|
- AssocSplatNode
|
2691
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
|
+
^^^^^
|
2692
2810
|
- name: opening_loc
|
2693
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
|
+
^
|
2694
2820
|
- name: closing_loc
|
2695
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
|
+
^
|
2696
2830
|
comment: |
|
2697
2831
|
Represents a hash pattern in pattern matching.
|
2698
2832
|
|
@@ -2701,6 +2835,12 @@ nodes:
|
|
2701
2835
|
|
2702
2836
|
foo => { a: 1, b: 2, **c }
|
2703
2837
|
^^^^^^^^^^^^^^^^^^^
|
2838
|
+
|
2839
|
+
foo => Bar[a: 1, b: 2]
|
2840
|
+
^^^^^^^^^^^^^^^
|
2841
|
+
|
2842
|
+
foo in { a: 1, b: 2 }
|
2843
|
+
^^^^^^^^^^^^^^
|
2704
2844
|
- name: IfNode
|
2705
2845
|
fields:
|
2706
2846
|
- name: if_keyword_loc
|
@@ -3353,6 +3493,9 @@ nodes:
|
|
3353
3493
|
|
3354
3494
|
foo, bar = baz
|
3355
3495
|
^^^ ^^^
|
3496
|
+
|
3497
|
+
foo => baz
|
3498
|
+
^^^
|
3356
3499
|
- name: LocalVariableWriteNode
|
3357
3500
|
fields:
|
3358
3501
|
- name: name
|
@@ -3443,11 +3586,65 @@ nodes:
|
|
3443
3586
|
- name: value
|
3444
3587
|
type: node
|
3445
3588
|
kind: non-void expression
|
3589
|
+
comment: |
|
3590
|
+
Represents the left-hand side of the operator.
|
3591
|
+
|
3592
|
+
foo => bar
|
3593
|
+
^^^
|
3446
3594
|
- name: pattern
|
3447
3595
|
type: node
|
3448
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
|
3449
3641
|
- name: operator_loc
|
3450
3642
|
type: location
|
3643
|
+
comment: |
|
3644
|
+
The location of the operator.
|
3645
|
+
|
3646
|
+
foo => bar
|
3647
|
+
^^
|
3451
3648
|
comment: |
|
3452
3649
|
Represents the use of the `=>` operator.
|
3453
3650
|
|
@@ -3877,12 +4074,32 @@ nodes:
|
|
3877
4074
|
- name: expression
|
3878
4075
|
type: node
|
3879
4076
|
kind: non-void expression
|
4077
|
+
comment: |
|
4078
|
+
The expression used in the pinned expression
|
4079
|
+
|
4080
|
+
foo in ^(bar)
|
4081
|
+
^^^
|
3880
4082
|
- name: operator_loc
|
3881
4083
|
type: location
|
4084
|
+
comment: |
|
4085
|
+
The location of the `^` operator
|
4086
|
+
|
4087
|
+
foo in ^(bar)
|
4088
|
+
^
|
3882
4089
|
- name: lparen_loc
|
3883
4090
|
type: location
|
4091
|
+
comment: |
|
4092
|
+
The location of the opening parenthesis.
|
4093
|
+
|
4094
|
+
foo in ^(bar)
|
4095
|
+
^
|
3884
4096
|
- name: rparen_loc
|
3885
4097
|
type: location
|
4098
|
+
comment: |
|
4099
|
+
The location of the closing parenthesis.
|
4100
|
+
|
4101
|
+
foo in ^(bar)
|
4102
|
+
^
|
3886
4103
|
comment: |
|
3887
4104
|
Represents the use of the `^` operator for pinning an expression in a pattern matching expression.
|
3888
4105
|
|
@@ -3901,8 +4118,18 @@ nodes:
|
|
3901
4118
|
- NumberedReferenceReadNode # foo in ^$1
|
3902
4119
|
- ItLocalVariableReadNode # proc { 1 in ^it }
|
3903
4120
|
- on error: MissingNode # foo in ^Bar
|
4121
|
+
comment: |
|
4122
|
+
The variable used in the pinned expression
|
4123
|
+
|
4124
|
+
foo in ^bar
|
4125
|
+
^^^
|
3904
4126
|
- name: operator_loc
|
3905
4127
|
type: location
|
4128
|
+
comment: |
|
4129
|
+
The location of the `^` operator
|
4130
|
+
|
4131
|
+
foo in ^bar
|
4132
|
+
^
|
3906
4133
|
comment: |
|
3907
4134
|
Represents the use of the `^` operator for pinning a variable in a pattern matching expression.
|
3908
4135
|
|
data/docs/parser_translation.md
CHANGED
@@ -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
|
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
|
-
|
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
|
-
|
30
|
-
|
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
|
-
|
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
|
-
|
39
|
-
https://
|
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.
|
data/docs/ripper_translation.md
CHANGED
@@ -55,7 +55,7 @@ It is helpful to understand the differences between the `Ripper` library and the
|
|
55
55
|
|
56
56
|
### Design
|
57
57
|
|
58
|
-
`Ripper` is a streaming parser. This means as it is parsing Ruby code, it dispatches events back to the consumer. This allows quite a bit of flexibility. You can use it to build your own syntax tree or to find specific patterns in the code. `Prism` on the other hand returns to
|
58
|
+
`Ripper` is a streaming parser. This means as it is parsing Ruby code, it dispatches events back to the consumer. This allows quite a bit of flexibility. You can use it to build your own syntax tree or to find specific patterns in the code. `Prism` on the other hand returns to you the completed syntax tree _before_ it allows you to manipulate it. This means the tree that you get back is the only representation that can be generated by the parser _at parse time_ (but of course can be manipulated later).
|
59
59
|
|
60
60
|
### Fields
|
61
61
|
|
data/ext/prism/api_node.c
CHANGED
data/ext/prism/extension.c
CHANGED
@@ -994,6 +994,14 @@ profile_file(int argc, VALUE *argv, VALUE self) {
|
|
994
994
|
return Qnil;
|
995
995
|
}
|
996
996
|
|
997
|
+
static int
|
998
|
+
parse_stream_eof(void *stream) {
|
999
|
+
if (rb_funcall((VALUE) stream, rb_intern("eof?"), 0)) {
|
1000
|
+
return 1;
|
1001
|
+
}
|
1002
|
+
return 0;
|
1003
|
+
}
|
1004
|
+
|
997
1005
|
/**
|
998
1006
|
* An implementation of fgets that is suitable for use with Ruby IO objects.
|
999
1007
|
*/
|
@@ -1034,7 +1042,7 @@ parse_stream(int argc, VALUE *argv, VALUE self) {
|
|
1034
1042
|
pm_parser_t parser;
|
1035
1043
|
pm_buffer_t buffer;
|
1036
1044
|
|
1037
|
-
pm_node_t *node = pm_parse_stream(&parser, &buffer, (void *) stream, parse_stream_fgets, &options);
|
1045
|
+
pm_node_t *node = pm_parse_stream(&parser, &buffer, (void *) stream, parse_stream_fgets, parse_stream_eof, &options);
|
1038
1046
|
rb_encoding *encoding = rb_enc_find(parser.encoding->name);
|
1039
1047
|
|
1040
1048
|
VALUE source = pm_source_new(&parser, encoding, options.freeze);
|
@@ -1331,6 +1339,11 @@ Init_prism(void) {
|
|
1331
1339
|
);
|
1332
1340
|
}
|
1333
1341
|
|
1342
|
+
#ifdef HAVE_RB_EXT_RACTOR_SAFE
|
1343
|
+
// Mark this extension as Ractor-safe.
|
1344
|
+
rb_ext_ractor_safe(true);
|
1345
|
+
#endif
|
1346
|
+
|
1334
1347
|
// Grab up references to all of the constants that we're going to need to
|
1335
1348
|
// reference throughout this extension.
|
1336
1349
|
rb_cPrism = rb_define_module("Prism");
|