prism 0.19.0 → 0.20.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +29 -1
  3. data/Makefile +5 -0
  4. data/README.md +8 -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 +3 -3
  11. data/docs/ruby_api.md +1 -1
  12. data/docs/serialization.md +17 -5
  13. data/ext/prism/api_node.c +101 -81
  14. data/ext/prism/extension.c +74 -11
  15. data/ext/prism/extension.h +1 -1
  16. data/include/prism/ast.h +1699 -504
  17. data/include/prism/defines.h +8 -0
  18. data/include/prism/diagnostic.h +39 -2
  19. data/include/prism/encoding.h +10 -0
  20. data/include/prism/options.h +40 -14
  21. data/include/prism/parser.h +33 -17
  22. data/include/prism/util/pm_buffer.h +9 -0
  23. data/include/prism/util/pm_constant_pool.h +7 -0
  24. data/include/prism/util/pm_newline_list.h +0 -11
  25. data/include/prism/version.h +2 -2
  26. data/include/prism.h +19 -2
  27. data/lib/prism/debug.rb +11 -5
  28. data/lib/prism/dot_visitor.rb +36 -14
  29. data/lib/prism/dsl.rb +22 -22
  30. data/lib/prism/ffi.rb +2 -2
  31. data/lib/prism/node.rb +1020 -737
  32. data/lib/prism/node_ext.rb +2 -2
  33. data/lib/prism/parse_result.rb +17 -9
  34. data/lib/prism/serialize.rb +53 -29
  35. data/lib/prism/translation/parser/compiler.rb +1831 -0
  36. data/lib/prism/translation/parser/lexer.rb +335 -0
  37. data/lib/prism/translation/parser/rubocop.rb +37 -0
  38. data/lib/prism/translation/parser.rb +163 -0
  39. data/lib/prism/translation.rb +11 -0
  40. data/lib/prism.rb +1 -0
  41. data/prism.gemspec +12 -5
  42. data/rbi/prism.rbi +150 -88
  43. data/rbi/prism_static.rbi +15 -3
  44. data/sig/prism.rbs +996 -961
  45. data/sig/prism_static.rbs +123 -46
  46. data/src/diagnostic.c +259 -219
  47. data/src/encoding.c +4 -8
  48. data/src/node.c +2 -6
  49. data/src/options.c +24 -5
  50. data/src/prettyprint.c +174 -42
  51. data/src/prism.c +1136 -328
  52. data/src/serialize.c +12 -9
  53. data/src/token_type.c +353 -4
  54. data/src/util/pm_buffer.c +11 -0
  55. data/src/util/pm_constant_pool.c +12 -11
  56. data/src/util/pm_newline_list.c +2 -14
  57. metadata +10 -3
  58. data/docs/building.md +0 -29
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/translation/parser"
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.
data/docs/releasing.md CHANGED
@@ -13,13 +13,13 @@ To release a new version of Prism, perform the following steps:
13
13
  * `ext/prism/extension.h` in the `EXPECTED_PRISM_VERSION` macro
14
14
  * `include/prism/version.h` in the version macros
15
15
  * `javascript/package.json` in the `version` field
16
- * `rust/prism-sys/tests/utils_tests.rs` in the `version_test` function
16
+ * `rust/ruby-prism-sys/tests/utils_tests.rs` in the `version_test` function
17
17
  * `templates/java/org/prism/Loader.java.erb` in the `load` function
18
18
  * `templates/javascript/src/deserialize.js.erb` in the version constants
19
19
  * `templates/lib/prism/serialize.rb.erb` in the version constants
20
20
  * Run `bundle install` to update the `Gemfile.lock` file.
21
- * Update `rust/prism-sys/Cargo.toml` to match the new version and run `cargo build`
22
- * Update `rust/prism/Cargo.toml` to match the new version and run `cargo build`
21
+ * Update `rust/ruby-prism-sys/Cargo.toml` to match the new version and run `cargo build`
22
+ * Update `rust/ruby-prism/Cargo.toml` to match the new version and run `cargo build`
23
23
  * Commit all of the updated files.
24
24
 
25
25
  ## Publishing
data/docs/ruby_api.md CHANGED
@@ -14,7 +14,7 @@ The full API is documented below.
14
14
 
15
15
  ## API
16
16
 
17
- * `Prism.dump(source, filepath)` - parse the syntax tree corresponding to the given source string and filepath, and serialize it to a string. Filepath can be nil.
17
+ * `Prism.dump(source)` - parse the syntax tree corresponding to the given source string, and serialize it to a string
18
18
  * `Prism.dump_file(filepath)` - parse the syntax tree corresponding to the given source file and serialize it to a string
19
19
  * `Prism.lex(source)` - parse the tokens corresponding to the given source string and return them as an array within a parse result
20
20
  * `Prism.lex_file(filepath)` - parse the tokens corresponding to the given source file and return them as an array within a parse result
@@ -51,12 +51,21 @@ The comment type is one of:
51
51
  | location | the location of the key of the magic comment |
52
52
  | location | the location of the value of the magic comment |
53
53
 
54
- ### diagnostic
54
+ ### error
55
55
 
56
56
  | # bytes | field |
57
57
  | --- | --- |
58
- | string | diagnostic message (ASCII-only characters) |
59
- | location | the location in the source this diagnostic applies to |
58
+ | string | error message (ASCII-only characters) |
59
+ | location | the location in the source this error applies to |
60
+ | `1` | the level of the error: `0` for `fatal` |
61
+
62
+ ## warning
63
+
64
+ | # bytes | field |
65
+ | --- | --- |
66
+ | string | warning message (ASCII-only characters) |
67
+ | location | the location in the source this warning applies to |
68
+ | `1` | the level of the warning: `0` for `default` and `1` for `verbose` |
60
69
 
61
70
  ## Structure
62
71
 
@@ -82,9 +91,9 @@ The header is structured like the following table:
82
91
  | magic comment* | magic comments |
83
92
  | location? | the optional location of the `__END__` keyword and its contents |
84
93
  | varuint | number of errors |
85
- | diagnostic* | errors |
94
+ | error* | errors |
86
95
  | varuint | number of warnings |
87
- | diagnostic* | warnings |
96
+ | warning* | warnings |
88
97
  | `4` | content pool offset |
89
98
  | varuint | content pool size |
90
99
 
@@ -175,9 +184,12 @@ The final argument to `pm_serialize_parse` is an optional string that controls t
175
184
  | ... | the encoding bytes |
176
185
  | `1` | frozen string literal |
177
186
  | `1` | suppress warnings |
187
+ | `1` | syntax version, see [pm_options_version_t](https://github.com/ruby/prism/blob/main/include/prism/options.h) for valid values |
178
188
  | `4` | the number of scopes |
179
189
  | ... | the scopes |
180
190
 
191
+ Scopes are ordered from the outermost scope to the innermost one.
192
+
181
193
  Each scope is layed out as follows:
182
194
 
183
195
  | # bytes | field |
data/ext/prism/api_node.c CHANGED
@@ -171,7 +171,7 @@ pm_location_new(pm_parser_t *parser, const uint8_t *start, const uint8_t *end, V
171
171
 
172
172
  VALUE
173
173
  pm_token_new(pm_parser_t *parser, pm_token_t *token, rb_encoding *encoding, VALUE source) {
174
- ID type = rb_intern(pm_token_type_to_str(token->type));
174
+ ID type = rb_intern(pm_token_type_name(token->type));
175
175
  VALUE location = pm_location_new(parser, token->start, token->end, source);
176
176
 
177
177
  VALUE argv[] = {
@@ -1362,23 +1362,27 @@ pm_ast_new(pm_parser_t *parser, pm_node_t *node, rb_encoding *encoding) {
1362
1362
  #line 144 "api_node.c.erb"
1363
1363
  case PM_BLOCK_LOCAL_VARIABLE_NODE: {
1364
1364
  pm_block_local_variable_node_t *cast = (pm_block_local_variable_node_t *) node;
1365
- VALUE argv[2];
1365
+ VALUE argv[3];
1366
+
1367
+ // flags
1368
+ #line 192 "api_node.c.erb"
1369
+ argv[0] = ULONG2NUM(node->flags & ~PM_NODE_FLAG_COMMON_MASK);
1366
1370
 
1367
1371
  // name
1368
1372
  #line 167 "api_node.c.erb"
1369
1373
  assert(cast->name != 0);
1370
- argv[0] = rb_id2sym(constants[cast->name - 1]);
1374
+ argv[1] = rb_id2sym(constants[cast->name - 1]);
1371
1375
 
1372
1376
  // location
1373
- argv[1] = pm_location_new(parser, node->location.start, node->location.end, source);
1377
+ argv[2] = pm_location_new(parser, node->location.start, node->location.end, source);
1374
1378
 
1375
- rb_ary_push(value_stack, rb_class_new_instance(2, argv, rb_cPrismBlockLocalVariableNode));
1379
+ rb_ary_push(value_stack, rb_class_new_instance(3, argv, rb_cPrismBlockLocalVariableNode));
1376
1380
  break;
1377
1381
  }
1378
1382
  #line 144 "api_node.c.erb"
1379
1383
  case PM_BLOCK_NODE: {
1380
1384
  pm_block_node_t *cast = (pm_block_node_t *) node;
1381
- VALUE argv[7];
1385
+ VALUE argv[6];
1382
1386
 
1383
1387
  // locals
1384
1388
  #line 173 "api_node.c.erb"
@@ -1388,52 +1392,52 @@ pm_ast_new(pm_parser_t *parser, pm_node_t *node, rb_encoding *encoding) {
1388
1392
  rb_ary_push(argv[0], rb_id2sym(constants[cast->locals.ids[index] - 1]));
1389
1393
  }
1390
1394
 
1391
- // locals_body_index
1392
- #line 189 "api_node.c.erb"
1393
- argv[1] = ULONG2NUM(cast->locals_body_index);
1394
-
1395
1395
  // parameters
1396
1396
  #line 155 "api_node.c.erb"
1397
- argv[2] = rb_ary_pop(value_stack);
1397
+ argv[1] = rb_ary_pop(value_stack);
1398
1398
 
1399
1399
  // body
1400
1400
  #line 155 "api_node.c.erb"
1401
- argv[3] = rb_ary_pop(value_stack);
1401
+ argv[2] = rb_ary_pop(value_stack);
1402
1402
 
1403
1403
  // opening_loc
1404
1404
  #line 180 "api_node.c.erb"
1405
- argv[4] = pm_location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source);
1405
+ argv[3] = pm_location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source);
1406
1406
 
1407
1407
  // closing_loc
1408
1408
  #line 180 "api_node.c.erb"
1409
- argv[5] = pm_location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source);
1409
+ argv[4] = pm_location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source);
1410
1410
 
1411
1411
  // location
1412
- argv[6] = pm_location_new(parser, node->location.start, node->location.end, source);
1412
+ argv[5] = pm_location_new(parser, node->location.start, node->location.end, source);
1413
1413
 
1414
- rb_ary_push(value_stack, rb_class_new_instance(7, argv, rb_cPrismBlockNode));
1414
+ rb_ary_push(value_stack, rb_class_new_instance(6, argv, rb_cPrismBlockNode));
1415
1415
  break;
1416
1416
  }
1417
1417
  #line 144 "api_node.c.erb"
1418
1418
  case PM_BLOCK_PARAMETER_NODE: {
1419
1419
  pm_block_parameter_node_t *cast = (pm_block_parameter_node_t *) node;
1420
- VALUE argv[4];
1420
+ VALUE argv[5];
1421
+
1422
+ // flags
1423
+ #line 192 "api_node.c.erb"
1424
+ argv[0] = ULONG2NUM(node->flags & ~PM_NODE_FLAG_COMMON_MASK);
1421
1425
 
1422
1426
  // name
1423
- argv[0] = cast->name == 0 ? Qnil : rb_id2sym(constants[cast->name - 1]);
1427
+ argv[1] = cast->name == 0 ? Qnil : rb_id2sym(constants[cast->name - 1]);
1424
1428
 
1425
1429
  // name_loc
1426
1430
  #line 183 "api_node.c.erb"
1427
- argv[1] = cast->name_loc.start == NULL ? Qnil : pm_location_new(parser, cast->name_loc.start, cast->name_loc.end, source);
1431
+ argv[2] = cast->name_loc.start == NULL ? Qnil : pm_location_new(parser, cast->name_loc.start, cast->name_loc.end, source);
1428
1432
 
1429
1433
  // operator_loc
1430
1434
  #line 180 "api_node.c.erb"
1431
- argv[2] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source);
1435
+ argv[3] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source);
1432
1436
 
1433
1437
  // location
1434
- argv[3] = pm_location_new(parser, node->location.start, node->location.end, source);
1438
+ argv[4] = pm_location_new(parser, node->location.start, node->location.end, source);
1435
1439
 
1436
- rb_ary_push(value_stack, rb_class_new_instance(4, argv, rb_cPrismBlockParameterNode));
1440
+ rb_ary_push(value_stack, rb_class_new_instance(5, argv, rb_cPrismBlockParameterNode));
1437
1441
  break;
1438
1442
  }
1439
1443
  #line 144 "api_node.c.erb"
@@ -2288,7 +2292,7 @@ pm_ast_new(pm_parser_t *parser, pm_node_t *node, rb_encoding *encoding) {
2288
2292
  #line 144 "api_node.c.erb"
2289
2293
  case PM_DEF_NODE: {
2290
2294
  pm_def_node_t *cast = (pm_def_node_t *) node;
2291
- VALUE argv[14];
2295
+ VALUE argv[13];
2292
2296
 
2293
2297
  // name
2294
2298
  #line 167 "api_node.c.erb"
@@ -2319,38 +2323,34 @@ pm_ast_new(pm_parser_t *parser, pm_node_t *node, rb_encoding *encoding) {
2319
2323
  rb_ary_push(argv[5], rb_id2sym(constants[cast->locals.ids[index] - 1]));
2320
2324
  }
2321
2325
 
2322
- // locals_body_index
2323
- #line 189 "api_node.c.erb"
2324
- argv[6] = ULONG2NUM(cast->locals_body_index);
2325
-
2326
2326
  // def_keyword_loc
2327
2327
  #line 180 "api_node.c.erb"
2328
- argv[7] = pm_location_new(parser, cast->def_keyword_loc.start, cast->def_keyword_loc.end, source);
2328
+ argv[6] = pm_location_new(parser, cast->def_keyword_loc.start, cast->def_keyword_loc.end, source);
2329
2329
 
2330
2330
  // operator_loc
2331
2331
  #line 183 "api_node.c.erb"
2332
- argv[8] = cast->operator_loc.start == NULL ? Qnil : pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source);
2332
+ argv[7] = cast->operator_loc.start == NULL ? Qnil : pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source);
2333
2333
 
2334
2334
  // lparen_loc
2335
2335
  #line 183 "api_node.c.erb"
2336
- argv[9] = cast->lparen_loc.start == NULL ? Qnil : pm_location_new(parser, cast->lparen_loc.start, cast->lparen_loc.end, source);
2336
+ argv[8] = cast->lparen_loc.start == NULL ? Qnil : pm_location_new(parser, cast->lparen_loc.start, cast->lparen_loc.end, source);
2337
2337
 
2338
2338
  // rparen_loc
2339
2339
  #line 183 "api_node.c.erb"
2340
- argv[10] = cast->rparen_loc.start == NULL ? Qnil : pm_location_new(parser, cast->rparen_loc.start, cast->rparen_loc.end, source);
2340
+ argv[9] = cast->rparen_loc.start == NULL ? Qnil : pm_location_new(parser, cast->rparen_loc.start, cast->rparen_loc.end, source);
2341
2341
 
2342
2342
  // equal_loc
2343
2343
  #line 183 "api_node.c.erb"
2344
- argv[11] = cast->equal_loc.start == NULL ? Qnil : pm_location_new(parser, cast->equal_loc.start, cast->equal_loc.end, source);
2344
+ argv[10] = cast->equal_loc.start == NULL ? Qnil : pm_location_new(parser, cast->equal_loc.start, cast->equal_loc.end, source);
2345
2345
 
2346
2346
  // end_keyword_loc
2347
2347
  #line 183 "api_node.c.erb"
2348
- argv[12] = cast->end_keyword_loc.start == NULL ? Qnil : pm_location_new(parser, cast->end_keyword_loc.start, cast->end_keyword_loc.end, source);
2348
+ argv[11] = cast->end_keyword_loc.start == NULL ? Qnil : pm_location_new(parser, cast->end_keyword_loc.start, cast->end_keyword_loc.end, source);
2349
2349
 
2350
2350
  // location
2351
- argv[13] = pm_location_new(parser, node->location.start, node->location.end, source);
2351
+ argv[12] = pm_location_new(parser, node->location.start, node->location.end, source);
2352
2352
 
2353
- rb_ary_push(value_stack, rb_class_new_instance(14, argv, rb_cPrismDefNode));
2353
+ rb_ary_push(value_stack, rb_class_new_instance(13, argv, rb_cPrismDefNode));
2354
2354
  break;
2355
2355
  }
2356
2356
  #line 144 "api_node.c.erb"
@@ -3442,29 +3442,33 @@ pm_ast_new(pm_parser_t *parser, pm_node_t *node, rb_encoding *encoding) {
3442
3442
  #line 144 "api_node.c.erb"
3443
3443
  case PM_KEYWORD_REST_PARAMETER_NODE: {
3444
3444
  pm_keyword_rest_parameter_node_t *cast = (pm_keyword_rest_parameter_node_t *) node;
3445
- VALUE argv[4];
3445
+ VALUE argv[5];
3446
+
3447
+ // flags
3448
+ #line 192 "api_node.c.erb"
3449
+ argv[0] = ULONG2NUM(node->flags & ~PM_NODE_FLAG_COMMON_MASK);
3446
3450
 
3447
3451
  // name
3448
- argv[0] = cast->name == 0 ? Qnil : rb_id2sym(constants[cast->name - 1]);
3452
+ argv[1] = cast->name == 0 ? Qnil : rb_id2sym(constants[cast->name - 1]);
3449
3453
 
3450
3454
  // name_loc
3451
3455
  #line 183 "api_node.c.erb"
3452
- argv[1] = cast->name_loc.start == NULL ? Qnil : pm_location_new(parser, cast->name_loc.start, cast->name_loc.end, source);
3456
+ argv[2] = cast->name_loc.start == NULL ? Qnil : pm_location_new(parser, cast->name_loc.start, cast->name_loc.end, source);
3453
3457
 
3454
3458
  // operator_loc
3455
3459
  #line 180 "api_node.c.erb"
3456
- argv[2] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source);
3460
+ argv[3] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source);
3457
3461
 
3458
3462
  // location
3459
- argv[3] = pm_location_new(parser, node->location.start, node->location.end, source);
3463
+ argv[4] = pm_location_new(parser, node->location.start, node->location.end, source);
3460
3464
 
3461
- rb_ary_push(value_stack, rb_class_new_instance(4, argv, rb_cPrismKeywordRestParameterNode));
3465
+ rb_ary_push(value_stack, rb_class_new_instance(5, argv, rb_cPrismKeywordRestParameterNode));
3462
3466
  break;
3463
3467
  }
3464
3468
  #line 144 "api_node.c.erb"
3465
3469
  case PM_LAMBDA_NODE: {
3466
3470
  pm_lambda_node_t *cast = (pm_lambda_node_t *) node;
3467
- VALUE argv[8];
3471
+ VALUE argv[7];
3468
3472
 
3469
3473
  // locals
3470
3474
  #line 173 "api_node.c.erb"
@@ -3474,34 +3478,30 @@ pm_ast_new(pm_parser_t *parser, pm_node_t *node, rb_encoding *encoding) {
3474
3478
  rb_ary_push(argv[0], rb_id2sym(constants[cast->locals.ids[index] - 1]));
3475
3479
  }
3476
3480
 
3477
- // locals_body_index
3478
- #line 189 "api_node.c.erb"
3479
- argv[1] = ULONG2NUM(cast->locals_body_index);
3480
-
3481
3481
  // operator_loc
3482
3482
  #line 180 "api_node.c.erb"
3483
- argv[2] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source);
3483
+ argv[1] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source);
3484
3484
 
3485
3485
  // opening_loc
3486
3486
  #line 180 "api_node.c.erb"
3487
- argv[3] = pm_location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source);
3487
+ argv[2] = pm_location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source);
3488
3488
 
3489
3489
  // closing_loc
3490
3490
  #line 180 "api_node.c.erb"
3491
- argv[4] = pm_location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source);
3491
+ argv[3] = pm_location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source);
3492
3492
 
3493
3493
  // parameters
3494
3494
  #line 155 "api_node.c.erb"
3495
- argv[5] = rb_ary_pop(value_stack);
3495
+ argv[4] = rb_ary_pop(value_stack);
3496
3496
 
3497
3497
  // body
3498
3498
  #line 155 "api_node.c.erb"
3499
- argv[6] = rb_ary_pop(value_stack);
3499
+ argv[5] = rb_ary_pop(value_stack);
3500
3500
 
3501
3501
  // location
3502
- argv[7] = pm_location_new(parser, node->location.start, node->location.end, source);
3502
+ argv[6] = pm_location_new(parser, node->location.start, node->location.end, source);
3503
3503
 
3504
- rb_ary_push(value_stack, rb_class_new_instance(8, argv, rb_cPrismLambdaNode));
3504
+ rb_ary_push(value_stack, rb_class_new_instance(7, argv, rb_cPrismLambdaNode));
3505
3505
  break;
3506
3506
  }
3507
3507
  #line 144 "api_node.c.erb"
@@ -3989,53 +3989,61 @@ pm_ast_new(pm_parser_t *parser, pm_node_t *node, rb_encoding *encoding) {
3989
3989
  #line 144 "api_node.c.erb"
3990
3990
  case PM_OPTIONAL_KEYWORD_PARAMETER_NODE: {
3991
3991
  pm_optional_keyword_parameter_node_t *cast = (pm_optional_keyword_parameter_node_t *) node;
3992
- VALUE argv[4];
3992
+ VALUE argv[5];
3993
+
3994
+ // flags
3995
+ #line 192 "api_node.c.erb"
3996
+ argv[0] = ULONG2NUM(node->flags & ~PM_NODE_FLAG_COMMON_MASK);
3993
3997
 
3994
3998
  // name
3995
3999
  #line 167 "api_node.c.erb"
3996
4000
  assert(cast->name != 0);
3997
- argv[0] = rb_id2sym(constants[cast->name - 1]);
4001
+ argv[1] = rb_id2sym(constants[cast->name - 1]);
3998
4002
 
3999
4003
  // name_loc
4000
4004
  #line 180 "api_node.c.erb"
4001
- argv[1] = pm_location_new(parser, cast->name_loc.start, cast->name_loc.end, source);
4005
+ argv[2] = pm_location_new(parser, cast->name_loc.start, cast->name_loc.end, source);
4002
4006
 
4003
4007
  // value
4004
4008
  #line 155 "api_node.c.erb"
4005
- argv[2] = rb_ary_pop(value_stack);
4009
+ argv[3] = rb_ary_pop(value_stack);
4006
4010
 
4007
4011
  // location
4008
- argv[3] = pm_location_new(parser, node->location.start, node->location.end, source);
4012
+ argv[4] = pm_location_new(parser, node->location.start, node->location.end, source);
4009
4013
 
4010
- rb_ary_push(value_stack, rb_class_new_instance(4, argv, rb_cPrismOptionalKeywordParameterNode));
4014
+ rb_ary_push(value_stack, rb_class_new_instance(5, argv, rb_cPrismOptionalKeywordParameterNode));
4011
4015
  break;
4012
4016
  }
4013
4017
  #line 144 "api_node.c.erb"
4014
4018
  case PM_OPTIONAL_PARAMETER_NODE: {
4015
4019
  pm_optional_parameter_node_t *cast = (pm_optional_parameter_node_t *) node;
4016
- VALUE argv[5];
4020
+ VALUE argv[6];
4021
+
4022
+ // flags
4023
+ #line 192 "api_node.c.erb"
4024
+ argv[0] = ULONG2NUM(node->flags & ~PM_NODE_FLAG_COMMON_MASK);
4017
4025
 
4018
4026
  // name
4019
4027
  #line 167 "api_node.c.erb"
4020
4028
  assert(cast->name != 0);
4021
- argv[0] = rb_id2sym(constants[cast->name - 1]);
4029
+ argv[1] = rb_id2sym(constants[cast->name - 1]);
4022
4030
 
4023
4031
  // name_loc
4024
4032
  #line 180 "api_node.c.erb"
4025
- argv[1] = pm_location_new(parser, cast->name_loc.start, cast->name_loc.end, source);
4033
+ argv[2] = pm_location_new(parser, cast->name_loc.start, cast->name_loc.end, source);
4026
4034
 
4027
4035
  // operator_loc
4028
4036
  #line 180 "api_node.c.erb"
4029
- argv[2] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source);
4037
+ argv[3] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source);
4030
4038
 
4031
4039
  // value
4032
4040
  #line 155 "api_node.c.erb"
4033
- argv[3] = rb_ary_pop(value_stack);
4041
+ argv[4] = rb_ary_pop(value_stack);
4034
4042
 
4035
4043
  // location
4036
- argv[4] = pm_location_new(parser, node->location.start, node->location.end, source);
4044
+ argv[5] = pm_location_new(parser, node->location.start, node->location.end, source);
4037
4045
 
4038
- rb_ary_push(value_stack, rb_class_new_instance(5, argv, rb_cPrismOptionalParameterNode));
4046
+ rb_ary_push(value_stack, rb_class_new_instance(6, argv, rb_cPrismOptionalParameterNode));
4039
4047
  break;
4040
4048
  }
4041
4049
  #line 144 "api_node.c.erb"
@@ -4343,37 +4351,45 @@ pm_ast_new(pm_parser_t *parser, pm_node_t *node, rb_encoding *encoding) {
4343
4351
  #line 144 "api_node.c.erb"
4344
4352
  case PM_REQUIRED_KEYWORD_PARAMETER_NODE: {
4345
4353
  pm_required_keyword_parameter_node_t *cast = (pm_required_keyword_parameter_node_t *) node;
4346
- VALUE argv[3];
4354
+ VALUE argv[4];
4355
+
4356
+ // flags
4357
+ #line 192 "api_node.c.erb"
4358
+ argv[0] = ULONG2NUM(node->flags & ~PM_NODE_FLAG_COMMON_MASK);
4347
4359
 
4348
4360
  // name
4349
4361
  #line 167 "api_node.c.erb"
4350
4362
  assert(cast->name != 0);
4351
- argv[0] = rb_id2sym(constants[cast->name - 1]);
4363
+ argv[1] = rb_id2sym(constants[cast->name - 1]);
4352
4364
 
4353
4365
  // name_loc
4354
4366
  #line 180 "api_node.c.erb"
4355
- argv[1] = pm_location_new(parser, cast->name_loc.start, cast->name_loc.end, source);
4367
+ argv[2] = pm_location_new(parser, cast->name_loc.start, cast->name_loc.end, source);
4356
4368
 
4357
4369
  // location
4358
- argv[2] = pm_location_new(parser, node->location.start, node->location.end, source);
4370
+ argv[3] = pm_location_new(parser, node->location.start, node->location.end, source);
4359
4371
 
4360
- rb_ary_push(value_stack, rb_class_new_instance(3, argv, rb_cPrismRequiredKeywordParameterNode));
4372
+ rb_ary_push(value_stack, rb_class_new_instance(4, argv, rb_cPrismRequiredKeywordParameterNode));
4361
4373
  break;
4362
4374
  }
4363
4375
  #line 144 "api_node.c.erb"
4364
4376
  case PM_REQUIRED_PARAMETER_NODE: {
4365
4377
  pm_required_parameter_node_t *cast = (pm_required_parameter_node_t *) node;
4366
- VALUE argv[2];
4378
+ VALUE argv[3];
4379
+
4380
+ // flags
4381
+ #line 192 "api_node.c.erb"
4382
+ argv[0] = ULONG2NUM(node->flags & ~PM_NODE_FLAG_COMMON_MASK);
4367
4383
 
4368
4384
  // name
4369
4385
  #line 167 "api_node.c.erb"
4370
4386
  assert(cast->name != 0);
4371
- argv[0] = rb_id2sym(constants[cast->name - 1]);
4387
+ argv[1] = rb_id2sym(constants[cast->name - 1]);
4372
4388
 
4373
4389
  // location
4374
- argv[1] = pm_location_new(parser, node->location.start, node->location.end, source);
4390
+ argv[2] = pm_location_new(parser, node->location.start, node->location.end, source);
4375
4391
 
4376
- rb_ary_push(value_stack, rb_class_new_instance(2, argv, rb_cPrismRequiredParameterNode));
4392
+ rb_ary_push(value_stack, rb_class_new_instance(3, argv, rb_cPrismRequiredParameterNode));
4377
4393
  break;
4378
4394
  }
4379
4395
  #line 144 "api_node.c.erb"
@@ -4440,23 +4456,27 @@ pm_ast_new(pm_parser_t *parser, pm_node_t *node, rb_encoding *encoding) {
4440
4456
  #line 144 "api_node.c.erb"
4441
4457
  case PM_REST_PARAMETER_NODE: {
4442
4458
  pm_rest_parameter_node_t *cast = (pm_rest_parameter_node_t *) node;
4443
- VALUE argv[4];
4459
+ VALUE argv[5];
4460
+
4461
+ // flags
4462
+ #line 192 "api_node.c.erb"
4463
+ argv[0] = ULONG2NUM(node->flags & ~PM_NODE_FLAG_COMMON_MASK);
4444
4464
 
4445
4465
  // name
4446
- argv[0] = cast->name == 0 ? Qnil : rb_id2sym(constants[cast->name - 1]);
4466
+ argv[1] = cast->name == 0 ? Qnil : rb_id2sym(constants[cast->name - 1]);
4447
4467
 
4448
4468
  // name_loc
4449
4469
  #line 183 "api_node.c.erb"
4450
- argv[1] = cast->name_loc.start == NULL ? Qnil : pm_location_new(parser, cast->name_loc.start, cast->name_loc.end, source);
4470
+ argv[2] = cast->name_loc.start == NULL ? Qnil : pm_location_new(parser, cast->name_loc.start, cast->name_loc.end, source);
4451
4471
 
4452
4472
  // operator_loc
4453
4473
  #line 180 "api_node.c.erb"
4454
- argv[2] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source);
4474
+ argv[3] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source);
4455
4475
 
4456
4476
  // location
4457
- argv[3] = pm_location_new(parser, node->location.start, node->location.end, source);
4477
+ argv[4] = pm_location_new(parser, node->location.start, node->location.end, source);
4458
4478
 
4459
- rb_ary_push(value_stack, rb_class_new_instance(4, argv, rb_cPrismRestParameterNode));
4479
+ rb_ary_push(value_stack, rb_class_new_instance(5, argv, rb_cPrismRestParameterNode));
4460
4480
  break;
4461
4481
  }
4462
4482
  #line 144 "api_node.c.erb"