prism 0.19.0 → 0.24.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +102 -1
  3. data/Makefile +5 -0
  4. data/README.md +9 -6
  5. data/config.yml +236 -38
  6. data/docs/build_system.md +19 -2
  7. data/docs/cruby_compilation.md +27 -0
  8. data/docs/parser_translation.md +34 -0
  9. data/docs/parsing_rules.md +19 -0
  10. data/docs/releasing.md +84 -16
  11. data/docs/ruby_api.md +1 -1
  12. data/docs/ruby_parser_translation.md +19 -0
  13. data/docs/serialization.md +19 -5
  14. data/ext/prism/api_node.c +1989 -1525
  15. data/ext/prism/extension.c +130 -30
  16. data/ext/prism/extension.h +2 -2
  17. data/include/prism/ast.h +1700 -505
  18. data/include/prism/defines.h +8 -0
  19. data/include/prism/diagnostic.h +49 -7
  20. data/include/prism/encoding.h +17 -0
  21. data/include/prism/options.h +40 -14
  22. data/include/prism/parser.h +34 -18
  23. data/include/prism/util/pm_buffer.h +9 -0
  24. data/include/prism/util/pm_constant_pool.h +18 -0
  25. data/include/prism/util/pm_newline_list.h +4 -14
  26. data/include/prism/util/pm_strpbrk.h +4 -1
  27. data/include/prism/version.h +2 -2
  28. data/include/prism.h +19 -2
  29. data/lib/prism/debug.rb +11 -5
  30. data/lib/prism/desugar_compiler.rb +225 -80
  31. data/lib/prism/dot_visitor.rb +36 -14
  32. data/lib/prism/dsl.rb +302 -299
  33. data/lib/prism/ffi.rb +107 -76
  34. data/lib/prism/lex_compat.rb +17 -1
  35. data/lib/prism/node.rb +4580 -2607
  36. data/lib/prism/node_ext.rb +27 -4
  37. data/lib/prism/parse_result.rb +75 -29
  38. data/lib/prism/serialize.rb +633 -305
  39. data/lib/prism/translation/parser/compiler.rb +1838 -0
  40. data/lib/prism/translation/parser/lexer.rb +335 -0
  41. data/lib/prism/translation/parser/rubocop.rb +45 -0
  42. data/lib/prism/translation/parser.rb +190 -0
  43. data/lib/prism/translation/parser33.rb +12 -0
  44. data/lib/prism/translation/parser34.rb +12 -0
  45. data/lib/prism/translation/ripper.rb +696 -0
  46. data/lib/prism/translation/ruby_parser.rb +1521 -0
  47. data/lib/prism/translation.rb +11 -0
  48. data/lib/prism.rb +1 -1
  49. data/prism.gemspec +18 -7
  50. data/rbi/prism.rbi +150 -88
  51. data/rbi/prism_static.rbi +15 -3
  52. data/sig/prism.rbs +996 -961
  53. data/sig/prism_static.rbs +123 -46
  54. data/src/diagnostic.c +264 -219
  55. data/src/encoding.c +21 -26
  56. data/src/node.c +2 -6
  57. data/src/options.c +29 -5
  58. data/src/prettyprint.c +176 -44
  59. data/src/prism.c +1499 -564
  60. data/src/serialize.c +35 -21
  61. data/src/token_type.c +353 -4
  62. data/src/util/pm_buffer.c +11 -0
  63. data/src/util/pm_constant_pool.c +37 -11
  64. data/src/util/pm_newline_list.c +6 -15
  65. data/src/util/pm_string.c +0 -7
  66. data/src/util/pm_strpbrk.c +122 -14
  67. metadata +16 -5
  68. data/docs/building.md +0 -29
  69. data/lib/prism/ripper_compat.rb +0 -207
data/config.yml CHANGED
@@ -347,6 +347,8 @@ flags:
347
347
  comment: "a call that could have been a local variable"
348
348
  - name: ATTRIBUTE_WRITE
349
349
  comment: "a call that is an attribute write, so the value being written should be returned"
350
+ - name: IGNORE_VISIBILITY
351
+ comment: "a call that ignores method visibility"
350
352
  comment: Flags for call nodes.
351
353
  - name: EncodingFlags
352
354
  values:
@@ -368,14 +370,19 @@ flags:
368
370
  comment: Flags for integer nodes that correspond to the base of the integer.
369
371
  - name: KeywordHashNodeFlags
370
372
  values:
371
- - name: STATIC_KEYS
372
- comment: "a keyword hash which only has `AssocNode` elements all with static literal keys, which means the elements can be treated as keyword arguments"
373
+ - name: SYMBOL_KEYS
374
+ comment: "a keyword hash which only has `AssocNode` elements all with symbol keys, which means the elements can be treated as keyword arguments"
373
375
  comment: Flags for keyword hash nodes.
374
376
  - name: LoopFlags
375
377
  values:
376
378
  - name: BEGIN_MODIFIER
377
379
  comment: "a loop after a begin statement, so the body is executed first before the condition"
378
380
  comment: Flags for while and until loop nodes.
381
+ - name: ParameterFlags
382
+ values:
383
+ - name: REPEATED_PARAMETER
384
+ comment: "a parameter name that has been repeated in the method signature"
385
+ comment: Flags for parameter nodes.
379
386
  - name: RangeFlags
380
387
  values:
381
388
  - name: EXCLUDE_END
@@ -468,10 +475,31 @@ nodes:
468
475
  fields:
469
476
  - name: left
470
477
  type: node
478
+ comment: |
479
+ Represents the left side of the expression. It can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression).
480
+
481
+ left and right
482
+ ^^^^
483
+
484
+ 1 && 2
485
+ ^
471
486
  - name: right
472
487
  type: node
488
+ comment: |
489
+ Represents the right side of the expression. It can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression).
490
+
491
+ left && right
492
+ ^^^^^
493
+
494
+ 1 and 2
495
+ ^
473
496
  - name: operator_loc
474
497
  type: location
498
+ comment: |
499
+ The location of the `and` keyword or the `&&` operator.
500
+
501
+ left and right
502
+ ^^^
475
503
  comment: |
476
504
  Represents the use of the `&&` operator or the `and` keyword.
477
505
 
@@ -501,8 +529,7 @@ nodes:
501
529
  - name: closing_loc
502
530
  type: location?
503
531
  comment: |
504
- Represents an array literal. This can be a regular array using brackets or
505
- a special array using % like %w or %i.
532
+ Represents an array literal. This can be a regular array using brackets or a special array using % like %w or %i.
506
533
 
507
534
  [1, 2, 3]
508
535
  ^^^^^^^^^
@@ -541,10 +568,34 @@ nodes:
541
568
  fields:
542
569
  - name: key
543
570
  type: node
571
+ comment: |
572
+ The key of the association. This can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression).
573
+
574
+ { a: b }
575
+ ^
576
+
577
+ { foo => bar }
578
+ ^^^
579
+
580
+ { def a; end => 1 }
581
+ ^^^^^^^^^^
544
582
  - name: value
545
- type: node?
583
+ type: node
584
+ comment: |
585
+ The value of the association, if present. This can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression).
586
+
587
+ { foo => bar }
588
+ ^^^
589
+
590
+ { x: 1 }
591
+ ^
546
592
  - name: operator_loc
547
593
  type: location?
594
+ comment: |
595
+ The location of the `=>` operator, if present.
596
+
597
+ { foo => bar }
598
+ ^^
548
599
  comment: |
549
600
  Represents a hash key/value pair.
550
601
 
@@ -554,8 +605,18 @@ nodes:
554
605
  fields:
555
606
  - name: value
556
607
  type: node?
608
+ comment: |
609
+ The value to be splatted, if present. Will be missing when keyword rest argument forwarding is used.
610
+
611
+ { **foo }
612
+ ^^^
557
613
  - name: operator_loc
558
614
  type: location
615
+ comment: |
616
+ The location of the `**` operator.
617
+
618
+ { **x }
619
+ ^^
559
620
  comment: |
560
621
  Represents a splat in a hash literal.
561
622
 
@@ -565,6 +626,12 @@ nodes:
565
626
  fields:
566
627
  - name: name
567
628
  type: constant
629
+ comment: |
630
+ The name of the back-reference variable, including the leading `$`.
631
+
632
+ $& # name `:$&`
633
+
634
+ $+ # name `:$+`
568
635
  comment: |
569
636
  Represents reading a reference to a field in the previous match.
570
637
 
@@ -609,6 +676,9 @@ nodes:
609
676
  ^^^^^^^^^^
610
677
  - name: BlockLocalVariableNode
611
678
  fields:
679
+ - name: flags
680
+ type: flags
681
+ kind: ParameterFlags
612
682
  - name: name
613
683
  type: constant
614
684
  comment: |
@@ -620,8 +690,6 @@ nodes:
620
690
  fields:
621
691
  - name: locals
622
692
  type: constant[]
623
- - name: locals_body_index
624
- type: uint32
625
693
  - name: parameters
626
694
  type: node?
627
695
  - name: body
@@ -633,10 +701,13 @@ nodes:
633
701
  comment: |
634
702
  Represents a block of ruby code.
635
703
 
636
- [1, 2, 3].each { |i| puts x }
637
- ^^^^^^^^^^^^^^
704
+ [1, 2, 3].each { |i| puts x }
705
+ ^^^^^^^^^^^^^^
638
706
  - name: BlockParameterNode
639
707
  fields:
708
+ - name: flags
709
+ type: flags
710
+ kind: ParameterFlags
640
711
  - name: name
641
712
  type: constant?
642
713
  - name: name_loc
@@ -712,6 +783,17 @@ nodes:
712
783
  kind: CallNodeFlags
713
784
  - name: receiver
714
785
  type: node?
786
+ comment: |
787
+ The object that the method is being called on. This can be either `nil` or any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression).
788
+
789
+ foo.bar
790
+ ^^^
791
+
792
+ +foo
793
+ ^^^
794
+
795
+ foo + bar
796
+ ^^^
715
797
  - name: call_operator_loc
716
798
  type: location?
717
799
  - name: name
@@ -950,6 +1032,12 @@ nodes:
950
1032
  fields:
951
1033
  - name: name
952
1034
  type: constant
1035
+ comment: |
1036
+ The name of the class variable, which is a `@@` followed by an [identifier](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#identifiers).
1037
+
1038
+ @@abc # name `:@@abc`
1039
+
1040
+ @@_test # name `:@@_test`
953
1041
  comment: |
954
1042
  Represents referencing a class variable.
955
1043
 
@@ -1120,6 +1208,12 @@ nodes:
1120
1208
  fields:
1121
1209
  - name: name
1122
1210
  type: constant
1211
+ comment: |
1212
+ The name of the [constant](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#constants).
1213
+
1214
+ X # name `:X`
1215
+
1216
+ SOME_CONSTANT # name `:SOME_CONSTANT`
1123
1217
  comment: |
1124
1218
  Represents referencing a constant.
1125
1219
 
@@ -1164,8 +1258,6 @@ nodes:
1164
1258
  type: node?
1165
1259
  - name: locals
1166
1260
  type: constant[]
1167
- - name: locals_body_index
1168
- type: uint32
1169
1261
  - name: def_keyword_loc
1170
1262
  type: location
1171
1263
  - name: operator_loc
@@ -1407,6 +1499,12 @@ nodes:
1407
1499
  fields:
1408
1500
  - name: name
1409
1501
  type: constant
1502
+ comment: |
1503
+ The name of the global variable, which is a `$` followed by an [identifier](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#identifier). Alternatively, it can be one of the special global variables designated by a symbol.
1504
+
1505
+ $foo # name `:$foo`
1506
+
1507
+ $_Test # name `:$_Test`
1410
1508
  comment: |
1411
1509
  Represents referencing a global variable.
1412
1510
 
@@ -1440,10 +1538,28 @@ nodes:
1440
1538
  fields:
1441
1539
  - name: opening_loc
1442
1540
  type: location
1541
+ comment: |
1542
+ The location of the opening brace.
1543
+
1544
+ { a => b }
1545
+ ^
1443
1546
  - name: elements
1444
1547
  type: node[]
1548
+ comment: |
1549
+ The elements of the hash. These can be either `AssocNode`s or `AssocSplatNode`s.
1550
+
1551
+ { a: b }
1552
+ ^^^^
1553
+
1554
+ { **foo }
1555
+ ^^^^^
1445
1556
  - name: closing_loc
1446
1557
  type: location
1558
+ comment: |
1559
+ The location of the closing brace.
1560
+
1561
+ { a => b }
1562
+ ^
1447
1563
  comment: |
1448
1564
  Represents a hash literal.
1449
1565
 
@@ -1507,14 +1623,16 @@ nodes:
1507
1623
  - name: value
1508
1624
  type: node
1509
1625
  comment: |
1510
- Represents a node that is implicitly being added to the tree but doesn't
1511
- correspond directly to a node in the source.
1626
+ Represents a node that is implicitly being added to the tree but doesn't correspond directly to a node in the source.
1512
1627
 
1513
1628
  { foo: }
1514
1629
  ^^^^
1515
1630
 
1516
1631
  { Foo: }
1517
1632
  ^^^^
1633
+
1634
+ foo in { bar: }
1635
+ ^^^^
1518
1636
  - name: ImplicitRestNode
1519
1637
  comment: |
1520
1638
  Represents using a trailing comma to indicate an implicit rest parameter.
@@ -1709,6 +1827,12 @@ nodes:
1709
1827
  fields:
1710
1828
  - name: name
1711
1829
  type: constant
1830
+ comment: |
1831
+ The name of the instance variable, which is a `@` followed by an [identifier](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#identifiers).
1832
+
1833
+ @x # name `:@x`
1834
+
1835
+ @_test # name `:@_test`
1712
1836
  comment: |
1713
1837
  Represents referencing an instance variable.
1714
1838
 
@@ -1761,9 +1885,7 @@ nodes:
1761
1885
  type: location
1762
1886
  newline: parts
1763
1887
  comment: |
1764
- Represents a regular expression literal that contains interpolation that
1765
- is being used in the predicate of a conditional to implicitly match
1766
- against the last line read by an IO object.
1888
+ Represents a regular expression literal that contains interpolation that is being used in the predicate of a conditional to implicitly match against the last line read by an IO object.
1767
1889
 
1768
1890
  if /foo #{bar} baz/ then end
1769
1891
  ^^^^^^^^^^^^^^^^
@@ -1840,6 +1962,9 @@ nodes:
1840
1962
  ^^^^
1841
1963
  - name: KeywordRestParameterNode
1842
1964
  fields:
1965
+ - name: flags
1966
+ type: flags
1967
+ kind: ParameterFlags
1843
1968
  - name: name
1844
1969
  type: constant?
1845
1970
  - name: name_loc
@@ -1856,8 +1981,6 @@ nodes:
1856
1981
  fields:
1857
1982
  - name: locals
1858
1983
  type: constant[]
1859
- - name: locals_body_index
1860
- type: uint32
1861
1984
  - name: operator_loc
1862
1985
  type: location
1863
1986
  - name: opening_loc
@@ -1930,12 +2053,33 @@ nodes:
1930
2053
  fields:
1931
2054
  - name: name
1932
2055
  type: constant
2056
+ comment: |
2057
+ The name of the local variable, which is an [identifier](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#identifiers).
2058
+
2059
+ x # name `:x`
2060
+
2061
+ _Test # name `:_Test`
2062
+
2063
+ Note that this can also be an underscore followed by a number for the default block parameters.
2064
+
2065
+ _1 # name `:_1`
2066
+
2067
+ Finally, for the default `it` block parameter, the name is `0it`. This is to distinguish it from an `it` local variable that is explicitly declared.
2068
+
2069
+ it # name `:0it`
2070
+
1933
2071
  - name: depth
1934
2072
  type: uint32
2073
+ comment: |
2074
+ The number of visible scopes that should be searched to find the origin of this local variable.
2075
+
2076
+ foo = 1; foo # depth 0
2077
+
2078
+ bar = 2; tap { bar } # depth 1
2079
+
2080
+ The specific rules for calculating the depth may differ from individual Ruby implementations, as they are not specified by the language. For more information, see [the Prism documentation](https://github.com/ruby/prism/blob/main/docs/local_variable_depth.md).
1935
2081
  comment: |
1936
- Represents reading a local variable. Note that this requires that a local
1937
- variable of the same name has already been written to in the same scope,
1938
- otherwise it is parsed as a method call.
2082
+ Represents reading a local variable. Note that this requires that a local variable of the same name has already been written to in the same scope, otherwise it is parsed as a method call.
1939
2083
 
1940
2084
  foo
1941
2085
  ^^^
@@ -1981,9 +2125,7 @@ nodes:
1981
2125
  - name: unescaped
1982
2126
  type: string
1983
2127
  comment: |
1984
- Represents a regular expression literal used in the predicate of a
1985
- conditional to implicitly match against the last line read by an IO
1986
- object.
2128
+ Represents a regular expression literal used in the predicate of a conditional to implicitly match against the last line read by an IO object.
1987
2129
 
1988
2130
  if /foo/i then end
1989
2131
  ^^^^^^
@@ -2021,15 +2163,13 @@ nodes:
2021
2163
  - name: targets
2022
2164
  type: node[]
2023
2165
  comment: |
2024
- Represents writing local variables using a regular expression match with
2025
- named capture groups.
2166
+ Represents writing local variables using a regular expression match with named capture groups.
2026
2167
 
2027
2168
  /(?<foo>bar)/ =~ baz
2028
2169
  ^^^^^^^^^^^^^^^^^^^^
2029
2170
  - name: MissingNode
2030
2171
  comment: |
2031
- Represents a node that is missing from the source and results in a syntax
2032
- error.
2172
+ Represents a node that is missing from the source and results in a syntax error.
2033
2173
  - name: ModuleNode
2034
2174
  fields:
2035
2175
  - name: locals
@@ -2122,8 +2262,7 @@ nodes:
2122
2262
  - name: maximum
2123
2263
  type: uint8
2124
2264
  comment: |
2125
- Represents an implicit set of parameters through the use of numbered
2126
- parameters within a block or lambda.
2265
+ Represents an implicit set of parameters through the use of numbered parameters within a block or lambda.
2127
2266
 
2128
2267
  -> { _1 + _2 }
2129
2268
  ^^^^^^^^^^^^^^
@@ -2131,6 +2270,14 @@ nodes:
2131
2270
  fields:
2132
2271
  - name: number
2133
2272
  type: uint32
2273
+ comment: |
2274
+ The (1-indexed, from the left) number of the capture group. Numbered references that would overflow a `uint32` result in a `number` of exactly `2**32 - 1`.
2275
+
2276
+ $1 # number `1`
2277
+
2278
+ $5432 # number `5432`
2279
+
2280
+ $4294967296 # number `4294967295`
2134
2281
  comment: |
2135
2282
  Represents reading a numbered reference to a capture in the previous match.
2136
2283
 
@@ -2138,6 +2285,9 @@ nodes:
2138
2285
  ^^
2139
2286
  - name: OptionalKeywordParameterNode
2140
2287
  fields:
2288
+ - name: flags
2289
+ type: flags
2290
+ kind: ParameterFlags
2141
2291
  - name: name
2142
2292
  type: constant
2143
2293
  - name: name_loc
@@ -2152,6 +2302,9 @@ nodes:
2152
2302
  end
2153
2303
  - name: OptionalParameterNode
2154
2304
  fields:
2305
+ - name: flags
2306
+ type: flags
2307
+ kind: ParameterFlags
2155
2308
  - name: name
2156
2309
  type: constant
2157
2310
  - name: name_loc
@@ -2170,10 +2323,31 @@ nodes:
2170
2323
  fields:
2171
2324
  - name: left
2172
2325
  type: node
2326
+ comment: |
2327
+ Represents the left side of the expression. It can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression).
2328
+
2329
+ left or right
2330
+ ^^^^
2331
+
2332
+ 1 || 2
2333
+ ^
2173
2334
  - name: right
2174
2335
  type: node
2336
+ comment: |
2337
+ Represents the right side of the expression. It can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression).
2338
+
2339
+ left || right
2340
+ ^^^^^
2341
+
2342
+ 1 or 2
2343
+ ^
2175
2344
  - name: operator_loc
2176
2345
  type: location
2346
+ comment: |
2347
+ The location of the `or` keyword or the `||` operator.
2348
+
2349
+ left or right
2350
+ ^^
2177
2351
  comment: |
2178
2352
  Represents the use of the `||` operator or the `or` keyword.
2179
2353
 
@@ -2227,8 +2401,7 @@ nodes:
2227
2401
  - name: rparen_loc
2228
2402
  type: location
2229
2403
  comment: |
2230
- Represents the use of the `^` operator for pinning an expression in a
2231
- pattern matching expression.
2404
+ Represents the use of the `^` operator for pinning an expression in a pattern matching expression.
2232
2405
 
2233
2406
  foo in ^(bar)
2234
2407
  ^^^^^^
@@ -2239,8 +2412,7 @@ nodes:
2239
2412
  - name: operator_loc
2240
2413
  type: location
2241
2414
  comment: |
2242
- Represents the use of the `^` operator for pinning a variable in a pattern
2243
- matching expression.
2415
+ Represents the use of the `^` operator for pinning a variable in a pattern matching expression.
2244
2416
 
2245
2417
  foo in ^bar
2246
2418
  ^^^^
@@ -2291,10 +2463,29 @@ nodes:
2291
2463
  kind: RangeFlags
2292
2464
  - name: left
2293
2465
  type: node?
2466
+ comment: |
2467
+ The left-hand side of the range, if present. It can be either `nil` or any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression).
2468
+
2469
+ 1...
2470
+ ^
2471
+
2472
+ hello...goodbye
2473
+ ^^^^^
2294
2474
  - name: right
2295
2475
  type: node?
2476
+ comment: |
2477
+ The right-hand side of the range, if present. It can be either `nil` or any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression).
2478
+
2479
+ ..5
2480
+ ^
2481
+
2482
+ 1...foo
2483
+ ^^^
2484
+ If neither right-hand or left-hand side was included, this will be a MissingNode.
2296
2485
  - name: operator_loc
2297
2486
  type: location
2487
+ comment: |
2488
+ The location of the `..` or `...` operator.
2298
2489
  comment: |
2299
2490
  Represents the use of the `..` or `...` operators.
2300
2491
 
@@ -2338,6 +2529,9 @@ nodes:
2338
2529
  ^^^^^^
2339
2530
  - name: RequiredKeywordParameterNode
2340
2531
  fields:
2532
+ - name: flags
2533
+ type: flags
2534
+ kind: ParameterFlags
2341
2535
  - name: name
2342
2536
  type: constant
2343
2537
  - name: name_loc
@@ -2350,6 +2544,9 @@ nodes:
2350
2544
  end
2351
2545
  - name: RequiredParameterNode
2352
2546
  fields:
2547
+ - name: flags
2548
+ type: flags
2549
+ kind: ParameterFlags
2353
2550
  - name: name
2354
2551
  type: constant
2355
2552
  comment: |
@@ -2397,10 +2594,12 @@ nodes:
2397
2594
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2398
2595
  end
2399
2596
 
2400
- `Foo, *splat, Bar` are in the `exceptions` field.
2401
- `ex` is in the `exception` field.
2597
+ `Foo, *splat, Bar` are in the `exceptions` field. `ex` is in the `exception` field.
2402
2598
  - name: RestParameterNode
2403
2599
  fields:
2600
+ - name: flags
2601
+ type: flags
2602
+ kind: ParameterFlags
2404
2603
  - name: name
2405
2604
  type: constant?
2406
2605
  - name: name_loc
@@ -2511,8 +2710,7 @@ nodes:
2511
2710
  - name: unescaped
2512
2711
  type: string
2513
2712
  comment: |
2514
- Represents a string literal, a string contained within a `%w` list, or
2515
- plain string content within an interpolated string.
2713
+ Represents a string literal, a string contained within a `%w` list, or plain string content within an interpolated string.
2516
2714
 
2517
2715
  "foo"
2518
2716
  ^^^^^
data/docs/build_system.md CHANGED
@@ -53,7 +53,7 @@ Because of course those files are not part of the git repository.
53
53
 
54
54
  ### Building prism as part of CRuby
55
55
 
56
- [This script](https://github.com/ruby/ruby/blob/32e828bb4a6c65a392b2300f3bdf93008c7b6f25/tool/sync_default_gems.rb#L399-L426) imports prism sources in CRuby.
56
+ [This script](https://github.com/ruby/ruby/blob/5124f9ac7513eb590c37717337c430cb93caa151/tool/sync_default_gems.rb#L399-L422) imports prism sources in CRuby.
57
57
 
58
58
  The script generates the templates when importing.
59
59
 
@@ -71,4 +71,21 @@ and links to `libprism.a` (to avoid exporting symbols, so no conflict when insta
71
71
 
72
72
  ### Building prism as part of JRuby
73
73
 
74
- TODO, probably similar to TruffleRuby.
74
+ TODO, similar to TruffleRuby.
75
+
76
+ ### Building prism from source as a C library
77
+
78
+ All of the source files match `src/**/*.c` and all of the headers match `include/**/*.h`.
79
+
80
+ If you want to build prism as a shared library and link against it, you should compile with:
81
+
82
+ * `-fPIC -shared` - Compile as a shared library
83
+ * `-DPRISM_EXPORT_SYMBOLS` - Export the symbols (by default nothing is exported)
84
+
85
+ #### Flags
86
+
87
+ `make` respects the `MAKEFLAGS` environment variable. As such, to speed up the build you can run:
88
+
89
+ ```
90
+ MAKEFLAGS="-j10" bundle exec rake compile
91
+ ```
@@ -0,0 +1,27 @@
1
+ # Compiling Prism's AST
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.
4
+
5
+ This document will describe, at a high level, how CRuby's compilation of Prism's AST works.
6
+
7
+ As described in the [build system documentation](build_system.md), there is a "push" Webhook set up within the Prism repo triggered on each new commit to send information about the commit to [git.ruby-lang.org](https://github.com/ruby/git.ruby-lang.org). This in turn runs [a script](https://github.com/ruby/ruby/blob/master/tool/sync_default_gems.rb) to sync over new changes in Prism to their corresponding files in Ruby. Any failures in this sync script will show alerts in the #alerts-sync channel in the RubyLang Slack. The result of this step is that files are synced from Prism into ruby/ruby for its use. It is also worth noting that [`common.mk`](https://github.com/ruby/ruby/blob/master/common.mk) contains a list of Prism files which it needs to correctly compile. If there are new Prism files added, this file should also be updated.
8
+
9
+ ruby/ruby uses the Prism code to generate an AST from which it can generate instruction sequences. Compilation in ruby/ruby has three main steps:
10
+
11
+ 1. Compute an AST
12
+
13
+ Syncing over the Prism code allows ruby/ruby to compute the AST using Prism. It currently does this within [`iseq.c`](https://github.com/ruby/ruby/blob/master/iseq.c) using the `pm_parser_init` fuction.
14
+
15
+ 2. Run a first pass of compilation
16
+
17
+ Once the AST has been created, it is recursively descended in order to compute the appropriate instruction sequences. This is the crux of compilation, and we go into more detail about nuances in the following paragraphs.
18
+
19
+ The code for this step is almost exclusively in [`prism_compile.c`](https://github.com/ruby/ruby/blob/master/prism_compile.c). The main function used for compilation is `pm_compile_node` which is essentially a huge switch statement over practically every node type which computes the appropriate instruction sequences for that node type. There are several convenience helpers, such as `PM_COMPILE`, `PM_COMPILE_POPPED`, `PM_COMPILE_NOT_POPPED` which all call into the `pm_compile_node` function.
20
+
21
+ There are also several functions, like `parse_string`, `parse_integer` which consume Prism nodes and return CRuby values. These are all called for their relevant types within the big switch statement.
22
+
23
+ The Prism compiler also uses a concept of "scope nodes" which are not standard Prism nodes in the AST, but instead nodes constructed within the compiler for the sole purpose of making compilation easier. Scope nodes are defined in [`prism_compile.h`](https://github.com/ruby/ruby/blob/master/prism_compile.h) and store information such as locals, local table size, local depth offset and the index lookup tables. Scope nodes can be generated for node types which have their own "scope".
24
+
25
+ 3. Run an optimization pass of compilation
26
+
27
+ After the instruction sequences are initially computed, there is an existing (non-Prism based) optimization pass of the instruction sequences. There are several optimizations currently inlined into step 2, however, most of them happen in this step. Specifically, any peephole optimizations happen in this step. By the end of step 2, however, the instruction sequences take the same form regardless of if the initial AST was generated by Prism or not. Therefore, step 3 is agnostic to the parser, and should not require any Prism specific code.
@@ -0,0 +1,34 @@
1
+ # parser translation
2
+
3
+ Prism ships with the ability to translate its syntax tree into the syntax tree used by the [whitequark/parser](https://github.com/whitequark/parser) gem. This allows you to use tools built on top of the `parser` gem with the `prism` parser.
4
+
5
+ ## Usage
6
+
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
+
9
+ You can use the `prism` parser like you would any other. After requiring the parser, you should be able to call any of the regular `Parser::Base` APIs that you would normally use.
10
+
11
+ ```ruby
12
+ require "prism"
13
+
14
+ Prism::Translation::Parser.parse_file("path/to/file.rb")
15
+ ```
16
+
17
+ ### RuboCop
18
+
19
+ To run RuboCop using the `prism` gem as the parser, you will need to require the `prism/translation/parser/rubocop` file. This file injects `prism` into the known options for both `rubocop` and `rubocop-ast`, such that you can specify it in your `.rubocop.yml` file. Unfortunately `rubocop` doesn't support any direct way to do this, so we have to get a bit hacky.
20
+
21
+ First, set the `TargetRubyVersion` in your RuboCop configuration file to `80_82_73_83_77.33`. This is the version of Ruby that `prism` reports itself as. (The leading numbers are the ASCII values for `PRISM`.)
22
+
23
+ ```yaml
24
+ AllCops:
25
+ TargetRubyVersion: 80_82_73_83_77.33
26
+ ```
27
+
28
+ Now when you run `rubocop` you will need to require the `prism/translation/parser/rubocop` file before executing so that it can inject the `prism` parser into the known options.
29
+
30
+ ```
31
+ bundle exec ruby -rprism/translation/parser/rubocop $(bundle exec which rubocop)
32
+ ```
33
+
34
+ This should run RuboCop using the `prism` parser.
@@ -0,0 +1,19 @@
1
+ # Rules
2
+
3
+ This document contains information related to the rules of the parser for Ruby source code.
4
+
5
+ As an example, in the documentation of many of the fields of nodes, it's mentioned that a field follows the lexing rules for `identifier` or `constant`. This document describes what those rules are.
6
+
7
+ ## Constants
8
+
9
+ Constants in Ruby begin with an upper-case letter. This is followed by any number of underscores, alphanumeric, or non-ASCII characters. The definition of "alphanumeric" and "upper-case letter" are encoding-dependent.
10
+
11
+ ## Non-void expression
12
+
13
+ Most expressions in CRuby are non-void. This means the expression they represent resolves to a value. For example, `1 + 2` is a non-void expression, because it resolves to a method call. Even things like `class Foo; end` is a non-void expression, because it returns the last evaluated expression in the body of the class (or `nil`).
14
+
15
+ Certain nodes, however, are void expressions, and cannot be combined to form larger expressions. For example, `BEGIN {}`, `END {}`, `alias foo bar`, and `undef foo`.
16
+
17
+ ## Identifiers
18
+
19
+ Identifiers in Ruby begin with an underscore or lower-case letter. This is followed by any number of underscores, alphanumeric, or non-ASCII characters. The definition of "alphanumeric" and "lower-case letter" are encoding-dependent.