parser 2.7.1.3 → 2.7.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +7 -7
- data/CHANGELOG.md +16 -1
- data/README.md +1 -0
- data/doc/AST_FORMAT.md +56 -2
- data/lib/parser/ast/processor.rb +2 -0
- data/lib/parser/builders/default.rb +50 -3
- data/lib/parser/context.rb +1 -0
- data/lib/parser/lexer.rl +8 -1
- data/lib/parser/macruby.y +14 -4
- data/lib/parser/meta.rb +2 -2
- data/lib/parser/ruby18.y +2 -0
- data/lib/parser/ruby19.y +14 -4
- data/lib/parser/ruby20.y +14 -4
- data/lib/parser/ruby21.y +9 -2
- data/lib/parser/ruby22.y +9 -2
- data/lib/parser/ruby23.y +9 -2
- data/lib/parser/ruby24.y +9 -2
- data/lib/parser/ruby25.y +9 -2
- data/lib/parser/ruby26.y +9 -2
- data/lib/parser/ruby27.y +15 -6
- data/lib/parser/ruby28.y +65 -38
- data/lib/parser/rubymotion.y +14 -4
- data/lib/parser/runner.rb +1 -1
- data/lib/parser/source/range.rb +1 -1
- data/lib/parser/source/tree_rewriter.rb +67 -1
- data/lib/parser/source/tree_rewriter/action.rb +39 -0
- data/lib/parser/version.rb +1 -1
- data/parser.gemspec +1 -1
- data/test/helper.rb +24 -0
- data/test/parse_helper.rb +16 -6
- data/test/test_parser.rb +225 -41
- data/test/test_source_tree_rewriter.rb +109 -11
- metadata +10 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c4dbd5dfd3a249d65b4d2b20c54b668749b3d5360e7feef7772924c135b78d86
|
4
|
+
data.tar.gz: ca30aca7f92a24fb96ef74c1a21149d9d43fb541d86bdae0b113f5ea5e267137
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: deb6edb6b828f309ebc6eb58e19613fe13c490e780895dfad01aceeeb0111781bc9e90b81bf6be35069afed44bd5f683c8120f134abd3d6aa7546a15fb370c19
|
7
|
+
data.tar.gz: 0c5a25dade42d9c74bc115aa8ecfd8dbfbcdeadc0fee6e994f44532ed994ac0c47aeccccc5405ddc9b5bd3804e4c47874163e6d468e47cb14ddd647ffb2c118c
|
data/.travis.yml
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
dist: trusty
|
2
2
|
language: ruby
|
3
|
-
|
3
|
+
jobs:
|
4
4
|
include:
|
5
|
+
- name: jruby-9.1.15.0 / Parser tests
|
6
|
+
rvm: jruby-9.1.15.0
|
7
|
+
script: bundle exec rake test
|
8
|
+
- name: truffleruby / Parser tests
|
9
|
+
rvm: truffleruby
|
10
|
+
script: TRUFFLERUBYOPT=--engine.Mode=latency bundle exec rake test
|
5
11
|
- name: 2.4.10 / Parser tests
|
6
12
|
rvm: 2.4.10
|
7
13
|
script: bundle exec rake test_cov
|
@@ -17,12 +23,6 @@ matrix:
|
|
17
23
|
- name: ruby-head / Parser tests
|
18
24
|
rvm: ruby-head
|
19
25
|
script: bundle exec rake test_cov
|
20
|
-
- name: jruby-9.1.15.0 / Parser tests
|
21
|
-
rvm: jruby-9.1.15.0
|
22
|
-
script: bundle exec rake test
|
23
|
-
- name: truffleruby / Parser tests
|
24
|
-
rvm: truffleruby
|
25
|
-
script: bundle exec rake test
|
26
26
|
- name: 2.5.8 / Rubocop tests
|
27
27
|
rvm: 2.5.8
|
28
28
|
script: ./ci/run_rubocop_specs
|
data/CHANGELOG.md
CHANGED
@@ -1,9 +1,24 @@
|
|
1
1
|
Changelog
|
2
2
|
=========
|
3
3
|
|
4
|
-
Not released (2020-
|
4
|
+
Not released (2020-06-19)
|
5
5
|
-------------------------
|
6
6
|
|
7
|
+
Features implemented:
|
8
|
+
* ruby28.y: add find pattern. (#714) (Ilya Bylich)
|
9
|
+
* lexer.rl: reject `->...` and `->(...)` with the same error. (#713) (Ilya Bylich)
|
10
|
+
* ruby28.y: accept leading args before forward arg. (#712) (Ilya Bylich)
|
11
|
+
* Added `emit_forward_arg` compatibility flag. (#710) (Ilya Bylich)
|
12
|
+
* ruby28.y: include entire lambda expr in lambda rule. (#708) (Ilya Bylich)
|
13
|
+
* ruby28.y: extracted excessed_comma rule. (#706) (Ilya Bylich)
|
14
|
+
* Source::TreeRewriter: Improved merging and representations (#703) (Marc-André Lafortune)
|
15
|
+
|
16
|
+
Bugs fixed:
|
17
|
+
* ruby*.y: fixed context inside lambda args and module. (#709) (Ilya Bylich)
|
18
|
+
|
19
|
+
v2.7.1.3 (2020-05-26)
|
20
|
+
---------------------
|
21
|
+
|
7
22
|
API modifications:
|
8
23
|
* fixed all warnings. tests are running in verbose mode now. (#685) (Ilya Bylich)
|
9
24
|
|
data/README.md
CHANGED
@@ -29,6 +29,7 @@ below for explanation of `emit_*` calls):
|
|
29
29
|
Parser::Builders::Default.emit_encoding = true
|
30
30
|
Parser::Builders::Default.emit_index = true
|
31
31
|
Parser::Builders::Default.emit_arg_inside_procarg0 = true
|
32
|
+
Parser::Builders::Default.emit_forward_arg = true
|
32
33
|
|
33
34
|
Parse a chunk of code:
|
34
35
|
|
data/doc/AST_FORMAT.md
CHANGED
@@ -1164,13 +1164,13 @@ s(:numblock,
|
|
1164
1164
|
|
1165
1165
|
## Forward arguments
|
1166
1166
|
|
1167
|
-
### Method definition accepting forwarding arguments
|
1167
|
+
### Method definition accepting only forwarding arguments
|
1168
1168
|
|
1169
1169
|
Ruby 2.7 introduced a feature called "arguments forwarding".
|
1170
1170
|
When a method takes any arguments for forwarding them in the future
|
1171
1171
|
the whole `args` node gets replaced with `forward-args` node.
|
1172
1172
|
|
1173
|
-
Format:
|
1173
|
+
Format if `emit_forward_arg` compatibility flag is disabled:
|
1174
1174
|
|
1175
1175
|
~~~
|
1176
1176
|
(def :foo
|
@@ -1181,6 +1181,25 @@ Format:
|
|
1181
1181
|
~~~~~ expression
|
1182
1182
|
~~~
|
1183
1183
|
|
1184
|
+
However, Ruby 2.8 added support for leading arguments before `...`, and so
|
1185
|
+
it can't be used as a replacement of the `(args)` node anymore. To solve it
|
1186
|
+
`emit_forward_arg` should be enabled.
|
1187
|
+
|
1188
|
+
Format if `emit_forward_arg` compatibility flag is enabled:
|
1189
|
+
|
1190
|
+
~~~
|
1191
|
+
(def :foo
|
1192
|
+
(args
|
1193
|
+
(forward-arg)) nil)
|
1194
|
+
"def foo(...); end"
|
1195
|
+
~ begin (args)
|
1196
|
+
~ end (args)
|
1197
|
+
~~~~~ expression (args)
|
1198
|
+
~~~ expression (forward_arg)
|
1199
|
+
~~~
|
1200
|
+
|
1201
|
+
Note that the node is called `forward_arg` when emitted separately.
|
1202
|
+
|
1184
1203
|
### Method call taking arguments of the currently forwarding method
|
1185
1204
|
|
1186
1205
|
Format:
|
@@ -2172,6 +2191,24 @@ Format:
|
|
2172
2191
|
~~~ name (match-nil-pattern)
|
2173
2192
|
~~~
|
2174
2193
|
|
2194
|
+
### Matching using find pattern
|
2195
|
+
|
2196
|
+
Format:
|
2197
|
+
|
2198
|
+
~~~
|
2199
|
+
(find-pattern
|
2200
|
+
(match-rest
|
2201
|
+
(match-var :a))
|
2202
|
+
(int 42)
|
2203
|
+
(match-rest))
|
2204
|
+
"in [*, 42, *]"
|
2205
|
+
~ begin
|
2206
|
+
~ end
|
2207
|
+
~~~~~~~~~~ expression
|
2208
|
+
~~~
|
2209
|
+
|
2210
|
+
Note that it can be used as a top-level pattern only when used in a `case` statement. In that case `begin` and `end` are empty.
|
2211
|
+
|
2175
2212
|
### Matching using const pattern
|
2176
2213
|
|
2177
2214
|
#### With array pattern
|
@@ -2227,3 +2264,20 @@ Format:
|
|
2227
2264
|
~ expression (const-pattern.const)
|
2228
2265
|
~~ expression (const-pattern.array_pattern)
|
2229
2266
|
~~~
|
2267
|
+
|
2268
|
+
#### With find pattern
|
2269
|
+
|
2270
|
+
Format:
|
2271
|
+
|
2272
|
+
~~~
|
2273
|
+
(const-pattern
|
2274
|
+
(const nil :X)
|
2275
|
+
(find-pattern
|
2276
|
+
(match-rest)
|
2277
|
+
(int 42)
|
2278
|
+
(match-rest)))
|
2279
|
+
"in X[*, 42, *]"
|
2280
|
+
~ begin
|
2281
|
+
~ end
|
2282
|
+
~~~~~~~~~~~ expression
|
2283
|
+
~~~
|
data/lib/parser/ast/processor.rb
CHANGED
@@ -127,6 +127,7 @@ module Parser
|
|
127
127
|
alias on_kwarg process_argument_node
|
128
128
|
alias on_kwoptarg process_argument_node
|
129
129
|
alias on_kwrestarg process_argument_node
|
130
|
+
alias on_forward_arg process_argument_node
|
130
131
|
|
131
132
|
def on_procarg0(node)
|
132
133
|
if node.children[0].is_a?(Symbol)
|
@@ -257,6 +258,7 @@ module Parser
|
|
257
258
|
alias on_array_pattern_with_tail process_regular_node
|
258
259
|
alias on_hash_pattern process_regular_node
|
259
260
|
alias on_const_pattern process_regular_node
|
261
|
+
alias on_find_pattern process_regular_node
|
260
262
|
|
261
263
|
# @private
|
262
264
|
def process_variable_node(node)
|
@@ -80,6 +80,8 @@ module Parser
|
|
80
80
|
attr_accessor :emit_index
|
81
81
|
end
|
82
82
|
|
83
|
+
@emit_index = false
|
84
|
+
|
83
85
|
class << self
|
84
86
|
##
|
85
87
|
# AST compatibility attribute; causes a single non-mlhs
|
@@ -95,7 +97,36 @@ module Parser
|
|
95
97
|
attr_accessor :emit_arg_inside_procarg0
|
96
98
|
end
|
97
99
|
|
98
|
-
@
|
100
|
+
@emit_arg_inside_procarg0 = false
|
101
|
+
|
102
|
+
class << self
|
103
|
+
##
|
104
|
+
# AST compatibility attribute; arguments forwarding initially
|
105
|
+
# didn't have support for leading arguments
|
106
|
+
# (i.e. `def m(a, ...); end` was a syntax error). However, Ruby 2.8
|
107
|
+
# added support for any number of arguments in front of the `...`.
|
108
|
+
#
|
109
|
+
# If set to false (the default):
|
110
|
+
# 1. `def m(...) end` is emitted as
|
111
|
+
# s(:def, :m, s(:forward_args), nil)
|
112
|
+
# 2. `def m(a, b, ...) end` is emitted as
|
113
|
+
# s(:def, :m,
|
114
|
+
# s(:args, s(:arg, :a), s(:arg, :b), s(:forward_arg)))
|
115
|
+
#
|
116
|
+
# If set to true it uses a single format:
|
117
|
+
# 1. `def m(...) end` is emitted as
|
118
|
+
# s(:def, :m, s(:args, s(:forward_arg)))
|
119
|
+
# 2. `def m(a, b, ...) end` is emitted as
|
120
|
+
# s(:def, :m, s(:args, s(:arg, :a), s(:arg, :b), s(:forward_arg)))
|
121
|
+
#
|
122
|
+
# It does't matter that much on 2.7 (because there can't be any leading arguments),
|
123
|
+
# but on 2.8 it should be better enabled to use a single AST format.
|
124
|
+
#
|
125
|
+
# @return [Boolean]
|
126
|
+
attr_accessor :emit_forward_arg
|
127
|
+
end
|
128
|
+
|
129
|
+
@emit_forward_arg = false
|
99
130
|
|
100
131
|
class << self
|
101
132
|
##
|
@@ -106,6 +137,7 @@ module Parser
|
|
106
137
|
@emit_encoding = true
|
107
138
|
@emit_index = true
|
108
139
|
@emit_arg_inside_procarg0 = true
|
140
|
+
@emit_forward_arg = true
|
109
141
|
end
|
110
142
|
end
|
111
143
|
|
@@ -709,8 +741,18 @@ module Parser
|
|
709
741
|
n(:numargs, [ max_numparam ], nil)
|
710
742
|
end
|
711
743
|
|
712
|
-
def
|
713
|
-
|
744
|
+
def forward_only_args(begin_t, dots_t, end_t)
|
745
|
+
if self.class.emit_forward_arg
|
746
|
+
arg = forward_arg(dots_t)
|
747
|
+
n(:args, [ arg ],
|
748
|
+
collection_map(begin_t, [ arg ], end_t))
|
749
|
+
else
|
750
|
+
n(:forward_args, [], collection_map(begin_t, token_map(dots_t), end_t))
|
751
|
+
end
|
752
|
+
end
|
753
|
+
|
754
|
+
def forward_arg(dots_t)
|
755
|
+
n(:forward_arg, [], token_map(dots_t))
|
714
756
|
end
|
715
757
|
|
716
758
|
def arg(name_t)
|
@@ -1358,6 +1400,11 @@ module Parser
|
|
1358
1400
|
collection_map(lbrack_t, elements, rbrack_t))
|
1359
1401
|
end
|
1360
1402
|
|
1403
|
+
def find_pattern(lbrack_t, elements, rbrack_t)
|
1404
|
+
n(:find_pattern, elements,
|
1405
|
+
collection_map(lbrack_t, elements, rbrack_t))
|
1406
|
+
end
|
1407
|
+
|
1361
1408
|
def match_with_trailing_comma(match, comma_t)
|
1362
1409
|
n(:match_with_trailing_comma, [ match ], expr_map(match.loc.expression.join(loc(comma_t))))
|
1363
1410
|
end
|
data/lib/parser/context.rb
CHANGED
@@ -5,6 +5,7 @@ module Parser
|
|
5
5
|
#
|
6
6
|
# Supported states:
|
7
7
|
# + :class - in the class body (class A; end)
|
8
|
+
# + :module - in the module body (module M; end)
|
8
9
|
# + :sclass - in the singleton class body (class << obj; end)
|
9
10
|
# + :def - in the method body (def m; end)
|
10
11
|
# + :defs - in the singleton method body (def self.m; end)
|
data/lib/parser/lexer.rl
CHANGED
@@ -2030,7 +2030,14 @@ class Parser::Lexer
|
|
2030
2030
|
|
2031
2031
|
'...'
|
2032
2032
|
=> {
|
2033
|
-
if @version >=
|
2033
|
+
if @version >= 28
|
2034
|
+
if @lambda_stack.any? && @lambda_stack.last + 1 == @paren_nest
|
2035
|
+
# To reject `->(...)` like `->...`
|
2036
|
+
emit(:tDOT3)
|
2037
|
+
else
|
2038
|
+
emit(:tBDOT3)
|
2039
|
+
end
|
2040
|
+
elsif @version >= 27
|
2034
2041
|
emit(:tBDOT3)
|
2035
2042
|
else
|
2036
2043
|
emit(:tDOT3)
|
data/lib/parser/macruby.y
CHANGED
@@ -1042,11 +1042,15 @@ rule
|
|
1042
1042
|
result = @builder.block(val[0],
|
1043
1043
|
begin_t, args, body, end_t)
|
1044
1044
|
}
|
1045
|
-
| tLAMBDA
|
1045
|
+
| tLAMBDA
|
1046
|
+
{
|
1047
|
+
@context.push(:lambda)
|
1048
|
+
}
|
1049
|
+
lambda
|
1046
1050
|
{
|
1047
1051
|
lambda_call = @builder.call_lambda(val[0])
|
1048
1052
|
|
1049
|
-
args, (begin_t, body, end_t) = val[
|
1053
|
+
args, (begin_t, body, end_t) = val[2]
|
1050
1054
|
result = @builder.block(lambda_call,
|
1051
1055
|
begin_t, args, body, end_t)
|
1052
1056
|
}
|
@@ -1160,6 +1164,7 @@ rule
|
|
1160
1164
|
{
|
1161
1165
|
@static_env.extend_static
|
1162
1166
|
@lexer.push_cmdarg
|
1167
|
+
@context.push(:module)
|
1163
1168
|
}
|
1164
1169
|
bodystmt kEND
|
1165
1170
|
{
|
@@ -1172,6 +1177,7 @@ rule
|
|
1172
1177
|
|
1173
1178
|
@lexer.pop_cmdarg
|
1174
1179
|
@static_env.unextend
|
1180
|
+
@context.pop
|
1175
1181
|
}
|
1176
1182
|
| kDEF fname
|
1177
1183
|
{
|
@@ -1453,9 +1459,13 @@ rule
|
|
1453
1459
|
lambda: {
|
1454
1460
|
@static_env.extend_dynamic
|
1455
1461
|
}
|
1456
|
-
f_larglist
|
1462
|
+
f_larglist
|
1463
|
+
{
|
1464
|
+
@context.pop
|
1465
|
+
}
|
1466
|
+
lambda_body
|
1457
1467
|
{
|
1458
|
-
result = [ val[1], val[
|
1468
|
+
result = [ val[1], val[3] ]
|
1459
1469
|
|
1460
1470
|
@static_env.unextend
|
1461
1471
|
}
|
data/lib/parser/meta.rb
CHANGED
@@ -26,12 +26,12 @@ module Parser
|
|
26
26
|
ident root lambda indexasgn index procarg0
|
27
27
|
restarg_expr blockarg_expr
|
28
28
|
objc_kwarg objc_restarg objc_varargs
|
29
|
-
numargs numblock forward_args forwarded_args
|
29
|
+
numargs numblock forward_args forwarded_args forward_arg
|
30
30
|
case_match in_match in_pattern
|
31
31
|
match_var pin match_alt match_as match_rest
|
32
32
|
array_pattern match_with_trailing_comma array_pattern_with_tail
|
33
33
|
hash_pattern const_pattern if_guard unless_guard match_nil_pattern
|
34
|
-
empty_else
|
34
|
+
empty_else find_pattern
|
35
35
|
).map(&:to_sym).to_set.freeze
|
36
36
|
|
37
37
|
end # Meta
|
data/lib/parser/ruby18.y
CHANGED
@@ -1156,6 +1156,7 @@ rule
|
|
1156
1156
|
| kMODULE cpath
|
1157
1157
|
{
|
1158
1158
|
@static_env.extend_static
|
1159
|
+
@context.push(:module)
|
1159
1160
|
}
|
1160
1161
|
bodystmt kEND
|
1161
1162
|
{
|
@@ -1167,6 +1168,7 @@ rule
|
|
1167
1168
|
val[3], val[4])
|
1168
1169
|
|
1169
1170
|
@static_env.unextend
|
1171
|
+
@context.pop
|
1170
1172
|
}
|
1171
1173
|
| kDEF fname
|
1172
1174
|
{
|
data/lib/parser/ruby19.y
CHANGED
@@ -1009,11 +1009,15 @@ rule
|
|
1009
1009
|
result = @builder.block(val[0],
|
1010
1010
|
begin_t, args, body, end_t)
|
1011
1011
|
}
|
1012
|
-
| tLAMBDA
|
1012
|
+
| tLAMBDA
|
1013
|
+
{
|
1014
|
+
@context.push(:lambda)
|
1015
|
+
}
|
1016
|
+
lambda
|
1013
1017
|
{
|
1014
1018
|
lambda_call = @builder.call_lambda(val[0])
|
1015
1019
|
|
1016
|
-
args, (begin_t, body, end_t) = val[
|
1020
|
+
args, (begin_t, body, end_t) = val[2]
|
1017
1021
|
result = @builder.block(lambda_call,
|
1018
1022
|
begin_t, args, body, end_t)
|
1019
1023
|
}
|
@@ -1127,6 +1131,7 @@ rule
|
|
1127
1131
|
{
|
1128
1132
|
@static_env.extend_static
|
1129
1133
|
@lexer.push_cmdarg
|
1134
|
+
@context.push(:module)
|
1130
1135
|
}
|
1131
1136
|
bodystmt kEND
|
1132
1137
|
{
|
@@ -1139,6 +1144,7 @@ rule
|
|
1139
1144
|
|
1140
1145
|
@lexer.pop_cmdarg
|
1141
1146
|
@static_env.unextend
|
1147
|
+
@context.pop
|
1142
1148
|
}
|
1143
1149
|
| kDEF fname
|
1144
1150
|
{
|
@@ -1433,9 +1439,13 @@ rule
|
|
1433
1439
|
lambda: {
|
1434
1440
|
@static_env.extend_dynamic
|
1435
1441
|
}
|
1436
|
-
f_larglist
|
1442
|
+
f_larglist
|
1443
|
+
{
|
1444
|
+
@context.pop
|
1445
|
+
}
|
1446
|
+
lambda_body
|
1437
1447
|
{
|
1438
|
-
result = [ val[1], val[
|
1448
|
+
result = [ val[1], val[3] ]
|
1439
1449
|
|
1440
1450
|
@static_env.unextend
|
1441
1451
|
}
|
data/lib/parser/ruby20.y
CHANGED
@@ -1039,11 +1039,15 @@ rule
|
|
1039
1039
|
result = @builder.block(val[0],
|
1040
1040
|
begin_t, args, body, end_t)
|
1041
1041
|
}
|
1042
|
-
| tLAMBDA
|
1042
|
+
| tLAMBDA
|
1043
|
+
{
|
1044
|
+
@context.push(:lambda)
|
1045
|
+
}
|
1046
|
+
lambda
|
1043
1047
|
{
|
1044
1048
|
lambda_call = @builder.call_lambda(val[0])
|
1045
1049
|
|
1046
|
-
args, (begin_t, body, end_t) = val[
|
1050
|
+
args, (begin_t, body, end_t) = val[2]
|
1047
1051
|
result = @builder.block(lambda_call,
|
1048
1052
|
begin_t, args, body, end_t)
|
1049
1053
|
}
|
@@ -1157,6 +1161,7 @@ rule
|
|
1157
1161
|
{
|
1158
1162
|
@static_env.extend_static
|
1159
1163
|
@lexer.push_cmdarg
|
1164
|
+
@context.push(:module)
|
1160
1165
|
}
|
1161
1166
|
bodystmt kEND
|
1162
1167
|
{
|
@@ -1169,6 +1174,7 @@ rule
|
|
1169
1174
|
|
1170
1175
|
@lexer.pop_cmdarg
|
1171
1176
|
@static_env.unextend
|
1177
|
+
@context.pop
|
1172
1178
|
}
|
1173
1179
|
| kDEF fname
|
1174
1180
|
{
|
@@ -1487,9 +1493,13 @@ opt_block_args_tail:
|
|
1487
1493
|
lambda: {
|
1488
1494
|
@static_env.extend_dynamic
|
1489
1495
|
}
|
1490
|
-
f_larglist
|
1496
|
+
f_larglist
|
1497
|
+
{
|
1498
|
+
@context.pop
|
1499
|
+
}
|
1500
|
+
lambda_body
|
1491
1501
|
{
|
1492
|
-
result = [ val[1], val[
|
1502
|
+
result = [ val[1], val[3] ]
|
1493
1503
|
|
1494
1504
|
@static_env.unextend
|
1495
1505
|
}
|