parser 2.7.0.0 → 2.7.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +6 -0
- data/CHANGELOG.md +28 -1
- data/README.md +6 -5
- data/doc/AST_FORMAT.md +41 -3
- data/lib/parser/ast/processor.rb +4 -0
- data/lib/parser/builders/default.rb +17 -7
- data/lib/parser/lexer.rl +6 -2
- data/lib/parser/lexer/dedenter.rb +5 -1
- data/lib/parser/messages.rb +1 -0
- data/lib/parser/meta.rb +1 -0
- data/lib/parser/ruby27.y +12 -5
- data/lib/parser/source/tree_rewriter/action.rb +2 -2
- data/lib/parser/version.rb +1 -1
- data/parser.gemspec +7 -0
- data/test/parse_helper.rb +3 -0
- data/test/test_parser.rb +72 -12
- data/test/test_source_comment_associator.rb +20 -20
- metadata +8 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 00a9bc5b2d70892e4743417168e53dc469c80328c3983e71b41f312becd116b0
|
4
|
+
data.tar.gz: 1abbc88751dc8d3b7c28d2df69b71a773533ed2d3726de50df8cfaaa79887aaa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 32455424b4003ba1510d53b162aa8691bdaea5708b4d88d392d6c89cfa3b6479f1d47c9f42fedd40e663366192434aaf851dbe65cbd1a629c54b7681cfb37879
|
7
|
+
data.tar.gz: 0c464e9acd5cf95161e18552e4680230417a05e7ad14e805b8661e4bb2ee7a99f4ad2f4e0212c48b35bc9f3ed8549b6723925f0b194e0a57873a2eb472450dbb
|
data/.travis.yml
CHANGED
@@ -20,6 +20,9 @@ matrix:
|
|
20
20
|
- name: 2.6.5 / Parser tests
|
21
21
|
rvm: 2.6.5
|
22
22
|
script: bundle exec rake test_cov
|
23
|
+
- name: 2.7.0 / Parser tests
|
24
|
+
rvm: 2.7.0
|
25
|
+
script: bundle exec rake test_cov
|
23
26
|
- name: ruby-head / Parser tests
|
24
27
|
rvm: ruby-head
|
25
28
|
script: bundle exec rake test_cov
|
@@ -35,6 +38,9 @@ matrix:
|
|
35
38
|
- name: 2.6.5 / Rubocop tests
|
36
39
|
rvm: 2.6.5
|
37
40
|
script: ./ci/run_rubocop_specs
|
41
|
+
- name: 2.7.0 / Rubocop tests
|
42
|
+
rvm: 2.7.0
|
43
|
+
script: ./ci/run_rubocop_specs
|
38
44
|
allow_failures:
|
39
45
|
- rvm: ruby-head
|
40
46
|
- rvm: rbx-2
|
data/CHANGELOG.md
CHANGED
@@ -1,9 +1,36 @@
|
|
1
1
|
Changelog
|
2
2
|
=========
|
3
3
|
|
4
|
-
Not released (
|
4
|
+
Not released (2020-03-20)
|
5
5
|
-------------------------
|
6
6
|
|
7
|
+
Features implemented:
|
8
|
+
* ruby27.y: fix array pattern with tail source map (#659) (Vladimir Dementyev)
|
9
|
+
|
10
|
+
Bugs fixed:
|
11
|
+
* builder.rb: fix constant_pattern source map (#660) (Vladimir Dementyev)
|
12
|
+
|
13
|
+
v2.7.0.4 (2020-03-02)
|
14
|
+
---------------------
|
15
|
+
|
16
|
+
Bugs fixed:
|
17
|
+
* lexer.rl: allow spaces before comments-before-leading-dot. (#654) (Ilya Bylich)
|
18
|
+
|
19
|
+
v2.7.0.2 (2020-01-08)
|
20
|
+
---------------------
|
21
|
+
|
22
|
+
Bugs fixed:
|
23
|
+
* lexer.rl: fix paren_nest for curly braces (#646) (Ilya Bylich)
|
24
|
+
|
25
|
+
v2.7.0.1 (2019-12-30)
|
26
|
+
---------------------
|
27
|
+
|
28
|
+
Bugs fixed:
|
29
|
+
* dedenter.rb: prevent `ArgumentError` when processing binary en… (#642) (Koichi ITO)
|
30
|
+
|
31
|
+
v2.7.0.0 (2019-12-26)
|
32
|
+
---------------------
|
33
|
+
|
7
34
|
API modifications:
|
8
35
|
* README.md: documented compatibility issue with EOF chars after… (#637) (Ilya Bylich)
|
9
36
|
* ruby27.y: refactor logic around 'circular argument reference'(#628) (Ilya Bylich)
|
data/README.md
CHANGED
@@ -24,10 +24,11 @@ below for explanation of `emit_*` calls):
|
|
24
24
|
|
25
25
|
require 'parser/current'
|
26
26
|
# opt-in to most recent AST format:
|
27
|
-
Parser::Builders::Default.emit_lambda
|
28
|
-
Parser::Builders::Default.emit_procarg0
|
29
|
-
Parser::Builders::Default.emit_encoding
|
30
|
-
Parser::Builders::Default.emit_index
|
27
|
+
Parser::Builders::Default.emit_lambda = true
|
28
|
+
Parser::Builders::Default.emit_procarg0 = true
|
29
|
+
Parser::Builders::Default.emit_encoding = true
|
30
|
+
Parser::Builders::Default.emit_index = true
|
31
|
+
Parser::Builders::Default.emit_arg_inside_procarg0 = true
|
31
32
|
|
32
33
|
Parse a chunk of code:
|
33
34
|
|
@@ -234,7 +235,7 @@ Parser implements the MacRuby 0.12 and RubyMotion mid-2015 parsers precisely. Ho
|
|
234
235
|
|
235
236
|
## Known issues
|
236
237
|
|
237
|
-
Adding support for the following Ruby MRI features in Parser would needlessly complicate it, and as they all are very specific and rarely
|
238
|
+
Adding support for the following Ruby MRI features in Parser would needlessly complicate it, and as they all are very specific and rarely occurring corner cases, this is not done.
|
238
239
|
|
239
240
|
Parser has been extensively tested; in particular, it parses almost entire [Rubygems][rg] corpus. For every issue, a breakdown of affected gems is offered.
|
240
241
|
|
data/doc/AST_FORMAT.md
CHANGED
@@ -1870,6 +1870,27 @@ Format:
|
|
1870
1870
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ expression
|
1871
1871
|
~~~
|
1872
1872
|
|
1873
|
+
#### With empty else
|
1874
|
+
|
1875
|
+
Empty `else` differs from the missing (or _implicit_) `else` for pattern matching, since
|
1876
|
+
the latter one raises a `NoMatchingPattern` exception. Thus, we need a way to distinguish this
|
1877
|
+
two cases in the resulting AST.
|
1878
|
+
|
1879
|
+
Format:
|
1880
|
+
|
1881
|
+
~~~
|
1882
|
+
(case-match,
|
1883
|
+
(str "str")
|
1884
|
+
(in-pattern
|
1885
|
+
(match-var :foo)
|
1886
|
+
(lvar :bar))
|
1887
|
+
(empty-else))
|
1888
|
+
"case "str"; in foo; bar; else; end"
|
1889
|
+
~~~~ keyword ~~~~ else
|
1890
|
+
~~~ end
|
1891
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ expression
|
1892
|
+
~~~
|
1893
|
+
|
1873
1894
|
### In clause
|
1874
1895
|
|
1875
1896
|
Format:
|
@@ -2047,7 +2068,7 @@ so a single item match with comma gets interpreted as an array.
|
|
2047
2068
|
(array-pattern-with-tail
|
2048
2069
|
(match-var :foo))
|
2049
2070
|
"in foo,"
|
2050
|
-
|
2071
|
+
~~~~ expression
|
2051
2072
|
~~~
|
2052
2073
|
|
2053
2074
|
### Matching using hash pattern
|
@@ -2118,7 +2139,7 @@ Format:
|
|
2118
2139
|
"in X[^foo bar]"
|
2119
2140
|
~ begin (const-pattern)
|
2120
2141
|
~ end (const-pattern)
|
2121
|
-
|
2142
|
+
~~~~~~~~~~~~ expression (const-pattern)
|
2122
2143
|
~ name (const-pattern.const)
|
2123
2144
|
~ expression (const-pattern.const)
|
2124
2145
|
~~~
|
@@ -2136,7 +2157,24 @@ Format:
|
|
2136
2157
|
"in X[foo:, bar:]"
|
2137
2158
|
~ begin (const-pattern)
|
2138
2159
|
~ end (const-pattern)
|
2139
|
-
|
2160
|
+
~~~~~~~~~~~~~ expression (const-pattern)
|
2161
|
+
~ name (const-pattern.const)
|
2162
|
+
~ expression (const-pattern.const)
|
2163
|
+
~~~
|
2164
|
+
|
2165
|
+
#### With array pattern without elements
|
2166
|
+
|
2167
|
+
Format:
|
2168
|
+
|
2169
|
+
~~~
|
2170
|
+
(const-pattern
|
2171
|
+
(const nil :X)
|
2172
|
+
(array-pattern))
|
2173
|
+
"in X[]"
|
2174
|
+
~ begin (const-pattern)
|
2175
|
+
~ end (const-pattern)
|
2176
|
+
~~~ expression (const-pattern)
|
2140
2177
|
~ name (const-pattern.const)
|
2141
2178
|
~ expression (const-pattern.const)
|
2179
|
+
~~ expression (const-pattern.array_pattern)
|
2142
2180
|
~~~
|
data/lib/parser/ast/processor.rb
CHANGED
@@ -1213,6 +1213,7 @@ module Parser
|
|
1213
1213
|
#
|
1214
1214
|
|
1215
1215
|
def case_match(case_t, expr, in_bodies, else_t, else_body, end_t)
|
1216
|
+
else_body = n(:empty_else, nil, token_map(else_t)) if else_t && !else_body
|
1216
1217
|
n(:case_match, [ expr, *(in_bodies << else_body)],
|
1217
1218
|
condition_map(case_t, expr, nil, nil, else_t, else_body, end_t))
|
1218
1219
|
end
|
@@ -1313,9 +1314,11 @@ module Parser
|
|
1313
1314
|
end
|
1314
1315
|
|
1315
1316
|
def array_pattern(lbrack_t, elements, rbrack_t)
|
1317
|
+
return n(:array_pattern, nil, collection_map(lbrack_t, [], rbrack_t)) if elements.nil?
|
1318
|
+
|
1316
1319
|
trailing_comma = false
|
1317
1320
|
|
1318
|
-
|
1321
|
+
node_elements = elements.map do |element|
|
1319
1322
|
if element.type == :match_with_trailing_comma
|
1320
1323
|
trailing_comma = true
|
1321
1324
|
element.children.first
|
@@ -1326,17 +1329,22 @@ module Parser
|
|
1326
1329
|
end
|
1327
1330
|
|
1328
1331
|
node_type = trailing_comma ? :array_pattern_with_tail : :array_pattern
|
1329
|
-
|
1332
|
+
|
1333
|
+
n(node_type, node_elements,
|
1330
1334
|
collection_map(lbrack_t, elements, rbrack_t))
|
1331
1335
|
end
|
1332
1336
|
|
1333
|
-
def match_with_trailing_comma(match)
|
1334
|
-
n(:match_with_trailing_comma, [ match ],
|
1337
|
+
def match_with_trailing_comma(match, comma_t)
|
1338
|
+
n(:match_with_trailing_comma, [ match ], expr_map(match.loc.expression.join(loc(comma_t))))
|
1335
1339
|
end
|
1336
1340
|
|
1337
1341
|
def const_pattern(const, ldelim_t, pattern, rdelim_t)
|
1338
1342
|
n(:const_pattern, [const, pattern],
|
1339
|
-
|
1343
|
+
Source::Map::Collection.new(
|
1344
|
+
loc(ldelim_t), loc(rdelim_t),
|
1345
|
+
const.loc.expression.join(loc(rdelim_t))
|
1346
|
+
)
|
1347
|
+
)
|
1340
1348
|
end
|
1341
1349
|
|
1342
1350
|
def pin(pin_t, var)
|
@@ -1369,11 +1377,13 @@ module Parser
|
|
1369
1377
|
pair_keyword(label, value)
|
1370
1378
|
else
|
1371
1379
|
begin_t, parts, end_t = label
|
1380
|
+
label_loc = loc(begin_t).join(loc(end_t))
|
1372
1381
|
|
1373
1382
|
# quoted label like "label": value
|
1374
1383
|
if (var_name = static_string(parts))
|
1375
|
-
|
1376
|
-
|
1384
|
+
check_duplicate_pattern_key(var_name, label_loc)
|
1385
|
+
else
|
1386
|
+
diagnostic :error, :pm_interp_in_var_name, nil, label_loc
|
1377
1387
|
end
|
1378
1388
|
|
1379
1389
|
pair_quoted(begin_t, parts, end_t, value)
|
data/lib/parser/lexer.rl
CHANGED
@@ -1064,7 +1064,6 @@ class Parser::Lexer
|
|
1064
1064
|
emit(:tRCURLY, '}'.freeze, p - 1, p)
|
1065
1065
|
@cond.lexpop
|
1066
1066
|
@cmdarg.lexpop
|
1067
|
-
@paren_nest -= 1
|
1068
1067
|
else
|
1069
1068
|
emit(:tSTRING_DEND, '}'.freeze, p - 1, p)
|
1070
1069
|
end
|
@@ -1079,6 +1078,8 @@ class Parser::Lexer
|
|
1079
1078
|
fbreak;
|
1080
1079
|
end
|
1081
1080
|
end
|
1081
|
+
|
1082
|
+
@paren_nest -= 1
|
1082
1083
|
};
|
1083
1084
|
|
1084
1085
|
action extend_interp_code {
|
@@ -2165,6 +2166,9 @@ class Parser::Lexer
|
|
2165
2166
|
emit_do
|
2166
2167
|
end
|
2167
2168
|
end
|
2169
|
+
if tok == '{'.freeze
|
2170
|
+
@paren_nest += 1
|
2171
|
+
end
|
2168
2172
|
@command_start = true
|
2169
2173
|
|
2170
2174
|
fnext expr_value; fbreak;
|
@@ -2469,7 +2473,7 @@ class Parser::Lexer
|
|
2469
2473
|
|
2470
2474
|
# Here we use '\n' instead of w_newline to not modify @newline_s
|
2471
2475
|
# and eventually properly emit tNL
|
2472
|
-
(w_space_comment '\n')+
|
2476
|
+
(c_space* w_space_comment '\n')+
|
2473
2477
|
=> {
|
2474
2478
|
if @version < 27
|
2475
2479
|
# Ruby before 2.7 doesn't support comments before leading dot.
|
@@ -34,7 +34,11 @@ module Parser
|
|
34
34
|
# Of course, lexer could do it but once again: it's all because of dedenting.
|
35
35
|
#
|
36
36
|
def dedent(string)
|
37
|
-
|
37
|
+
original_encoding = string.encoding
|
38
|
+
# Prevent the following error when processing binary encoded source.
|
39
|
+
# "\xC0".split # => ArgumentError (invalid byte sequence in UTF-8)
|
40
|
+
lines = string.force_encoding(Encoding::BINARY).split("\\\n")
|
41
|
+
lines.map! {|s| s.force_encoding(original_encoding) }
|
38
42
|
|
39
43
|
if @at_line_begin
|
40
44
|
lines_to_dedent = lines
|
data/lib/parser/messages.rb
CHANGED
@@ -70,6 +70,7 @@ module Parser
|
|
70
70
|
:circular_argument_reference => 'circular argument reference %{var_name}',
|
71
71
|
:pm_interp_in_var_name => 'symbol literal with interpolation is not allowed',
|
72
72
|
:lvar_name => "`%{name}' is not allowed as a local variable name",
|
73
|
+
:undefined_lvar => "no such local variable: `%{name}'",
|
73
74
|
:duplicate_variable_name => 'duplicate variable name %{name}',
|
74
75
|
:duplicate_pattern_key => 'duplicate hash pattern key %{name}',
|
75
76
|
|
data/lib/parser/meta.rb
CHANGED
data/lib/parser/ruby27.y
CHANGED
@@ -1784,7 +1784,7 @@ opt_block_args_tail:
|
|
1784
1784
|
# array patterns that end with comma
|
1785
1785
|
# like 1, 2,
|
1786
1786
|
# must be emitted as `array_pattern_with_tail`
|
1787
|
-
item = @builder.match_with_trailing_comma(val[0])
|
1787
|
+
item = @builder.match_with_trailing_comma(val[0], val[1])
|
1788
1788
|
result = @builder.array_pattern(nil, [ item ], nil)
|
1789
1789
|
}
|
1790
1790
|
| p_expr tCOMMA p_args
|
@@ -1841,7 +1841,8 @@ opt_block_args_tail:
|
|
1841
1841
|
}
|
1842
1842
|
| p_const tLPAREN2 rparen
|
1843
1843
|
{
|
1844
|
-
|
1844
|
+
pattern = @builder.array_pattern(val[1], nil, val[2])
|
1845
|
+
result = @builder.const_pattern(val[0], val[1], pattern, val[2])
|
1845
1846
|
}
|
1846
1847
|
| p_const p_lbracket p_args rbracket
|
1847
1848
|
{
|
@@ -1857,7 +1858,8 @@ opt_block_args_tail:
|
|
1857
1858
|
}
|
1858
1859
|
| p_const tLBRACK2 rbracket
|
1859
1860
|
{
|
1860
|
-
|
1861
|
+
pattern = @builder.array_pattern(val[1], nil, val[2])
|
1862
|
+
result = @builder.const_pattern(val[0], val[1], pattern, val[2])
|
1861
1863
|
}
|
1862
1864
|
| tLBRACK
|
1863
1865
|
{
|
@@ -1932,7 +1934,7 @@ opt_block_args_tail:
|
|
1932
1934
|
# array patterns that end with comma
|
1933
1935
|
# like [1, 2,]
|
1934
1936
|
# must be emitted as `array_pattern_with_tail`
|
1935
|
-
item = @builder.match_with_trailing_comma(val[0])
|
1937
|
+
item = @builder.match_with_trailing_comma(val[0], val[1])
|
1936
1938
|
result = [ item ]
|
1937
1939
|
}
|
1938
1940
|
| p_args_head p_arg tCOMMA
|
@@ -1940,7 +1942,7 @@ opt_block_args_tail:
|
|
1940
1942
|
# array patterns that end with comma
|
1941
1943
|
# like [1, 2,]
|
1942
1944
|
# must be emitted as `array_pattern_with_tail`
|
1943
|
-
last_item = @builder.match_with_trailing_comma(val[1])
|
1945
|
+
last_item = @builder.match_with_trailing_comma(val[1], val[2])
|
1944
1946
|
result = [ *val[0], last_item ]
|
1945
1947
|
}
|
1946
1948
|
|
@@ -2096,6 +2098,11 @@ opt_block_args_tail:
|
|
2096
2098
|
|
2097
2099
|
p_var_ref: tCARET tIDENTIFIER
|
2098
2100
|
{
|
2101
|
+
name = val[1][0]
|
2102
|
+
unless static_env.declared?(name)
|
2103
|
+
diagnostic :error, :undefined_lvar, { :name => name }, val[1]
|
2104
|
+
end
|
2105
|
+
|
2099
2106
|
lvar = @builder.accessible(@builder.ident(val[1]))
|
2100
2107
|
result = @builder.pin(val[0], lvar)
|
2101
2108
|
}
|
@@ -56,11 +56,11 @@ module Parser
|
|
56
56
|
if action.range == @range
|
57
57
|
merge(action)
|
58
58
|
else
|
59
|
-
|
59
|
+
place_in_hierarchy(action)
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
63
|
-
def
|
63
|
+
def place_in_hierarchy(action)
|
64
64
|
family = @children.group_by { |child| child.relationship_with(action) }
|
65
65
|
|
66
66
|
if family[:fusible]
|
data/lib/parser/version.rb
CHANGED
data/parser.gemspec
CHANGED
@@ -13,6 +13,13 @@ Gem::Specification.new do |spec|
|
|
13
13
|
spec.homepage = 'https://github.com/whitequark/parser'
|
14
14
|
spec.license = 'MIT'
|
15
15
|
|
16
|
+
spec.metadata = {
|
17
|
+
'bug_tracker_uri' => 'https://github.com/whitequark/parser/issues',
|
18
|
+
'changelog_uri' => "https://github.com/whitequark/parser/blob/v#{spec.version}/CHANGELOG.md",
|
19
|
+
'documentation_uri' => "https://www.rubydoc.info/gems/parser/#{spec.version}",
|
20
|
+
'source_code_uri' => "https://github.com/whitequark/parser/tree/v#{spec.version}"
|
21
|
+
}
|
22
|
+
|
16
23
|
spec.files = `git ls-files`.split + %w(
|
17
24
|
lib/parser/lexer.rb
|
18
25
|
lib/parser/ruby18.rb
|
data/test/parse_helper.rb
CHANGED
@@ -127,6 +127,9 @@ module ParseHelper
|
|
127
127
|
|
128
128
|
assert parser.instance_eval { @lexer }.cmdarg.empty?,
|
129
129
|
"(#{version}) expected cmdarg to be empty after parsing"
|
130
|
+
|
131
|
+
assert_equal 0, parser.instance_eval { @lexer.instance_eval { @paren_nest } },
|
132
|
+
"(#{version}) expected paren_nest to be 0 after parsing"
|
130
133
|
end
|
131
134
|
|
132
135
|
# Use like this:
|
data/test/test_parser.rb
CHANGED
@@ -7644,12 +7644,26 @@ class TestParser < Minitest::Test
|
|
7644
7644
|
%q{},
|
7645
7645
|
SINCE_2_7)
|
7646
7646
|
|
7647
|
+
assert_parses(
|
7648
|
+
s(:send,
|
7649
|
+
s(:send, nil, :a), :foo),
|
7650
|
+
%Q{a #\n #\n.foo\n},
|
7651
|
+
%q{},
|
7652
|
+
SINCE_2_7)
|
7653
|
+
|
7647
7654
|
assert_parses(
|
7648
7655
|
s(:csend,
|
7649
7656
|
s(:send, nil, :a), :foo),
|
7650
7657
|
%Q{a #\n#\n&.foo\n},
|
7651
7658
|
%q{},
|
7652
7659
|
SINCE_2_7)
|
7660
|
+
|
7661
|
+
assert_parses(
|
7662
|
+
s(:csend,
|
7663
|
+
s(:send, nil, :a), :foo),
|
7664
|
+
%Q{a #\n #\n&.foo\n},
|
7665
|
+
%q{},
|
7666
|
+
SINCE_2_7)
|
7653
7667
|
end
|
7654
7668
|
|
7655
7669
|
def test_comments_before_leading_dot__before_27
|
@@ -8408,7 +8422,7 @@ class TestParser < Minitest::Test
|
|
8408
8422
|
nil,
|
8409
8423
|
s(:nil)),
|
8410
8424
|
%q{in x, then nil},
|
8411
|
-
%q{
|
8425
|
+
%q{ ~~ expression (in_pattern.array_pattern_with_tail)}
|
8412
8426
|
)
|
8413
8427
|
|
8414
8428
|
assert_parses_pattern_match(
|
@@ -8454,7 +8468,7 @@ class TestParser < Minitest::Test
|
|
8454
8468
|
nil,
|
8455
8469
|
s(:nil)),
|
8456
8470
|
%q{in x, y, then nil},
|
8457
|
-
%q{
|
8471
|
+
%q{ ~~~~~ expression (in_pattern.array_pattern_with_tail)}
|
8458
8472
|
)
|
8459
8473
|
|
8460
8474
|
assert_parses_pattern_match(
|
@@ -8839,6 +8853,15 @@ class TestParser < Minitest::Test
|
|
8839
8853
|
)
|
8840
8854
|
end
|
8841
8855
|
|
8856
|
+
def test_pattern_matching_hash_with_string_interpolation_keys
|
8857
|
+
assert_diagnoses(
|
8858
|
+
[:error, :pm_interp_in_var_name],
|
8859
|
+
%q{case a; in "#{a}": 1; end},
|
8860
|
+
%q{ ~~~~~~~ location},
|
8861
|
+
SINCE_2_7
|
8862
|
+
)
|
8863
|
+
end
|
8864
|
+
|
8842
8865
|
def test_pattern_matching_keyword_variable
|
8843
8866
|
assert_parses_pattern_match(
|
8844
8867
|
s(:in_pattern,
|
@@ -8970,7 +8993,7 @@ class TestParser < Minitest::Test
|
|
8970
8993
|
nil,
|
8971
8994
|
s(:true)),
|
8972
8995
|
%q{in A(1, 2) then true},
|
8973
|
-
%q{
|
8996
|
+
%q{ ~~~~~~~ expression (in_pattern.const_pattern)
|
8974
8997
|
| ~ begin (in_pattern.const_pattern)
|
8975
8998
|
| ~ end (in_pattern.const_pattern)
|
8976
8999
|
| ~ expression (in_pattern.const_pattern.const)
|
@@ -8986,7 +9009,7 @@ class TestParser < Minitest::Test
|
|
8986
9009
|
nil,
|
8987
9010
|
s(:true)),
|
8988
9011
|
%q{in A(x:) then true},
|
8989
|
-
%q{
|
9012
|
+
%q{ ~~~~~ expression (in_pattern.const_pattern)
|
8990
9013
|
| ~ begin (in_pattern.const_pattern)
|
8991
9014
|
| ~ end (in_pattern.const_pattern)
|
8992
9015
|
| ~ expression (in_pattern.const_pattern.const)
|
@@ -8997,13 +9020,15 @@ class TestParser < Minitest::Test
|
|
8997
9020
|
s(:in_pattern,
|
8998
9021
|
s(:const_pattern,
|
8999
9022
|
s(:const, nil, :A),
|
9000
|
-
|
9023
|
+
s(:array_pattern)),
|
9001
9024
|
nil,
|
9002
9025
|
s(:true)),
|
9003
9026
|
%q{in A() then true},
|
9004
|
-
%q{
|
9027
|
+
%q{ ~~~ expression (in_pattern.const_pattern)
|
9005
9028
|
| ~ begin (in_pattern.const_pattern)
|
9006
|
-
| ~ end (in_pattern.const_pattern)
|
9029
|
+
| ~ end (in_pattern.const_pattern)
|
9030
|
+
| ~ expression (in_pattern.const_pattern.const)
|
9031
|
+
| ~~ expression (in_pattern.const_pattern.array_pattern)}
|
9007
9032
|
)
|
9008
9033
|
|
9009
9034
|
assert_parses_pattern_match(
|
@@ -9016,7 +9041,7 @@ class TestParser < Minitest::Test
|
|
9016
9041
|
nil,
|
9017
9042
|
s(:true)),
|
9018
9043
|
%q{in A[1, 2] then true},
|
9019
|
-
%q{
|
9044
|
+
%q{ ~~~~~~~ expression (in_pattern.const_pattern)
|
9020
9045
|
| ~ begin (in_pattern.const_pattern)
|
9021
9046
|
| ~ end (in_pattern.const_pattern)
|
9022
9047
|
| ~ expression (in_pattern.const_pattern.const)
|
@@ -9032,7 +9057,7 @@ class TestParser < Minitest::Test
|
|
9032
9057
|
nil,
|
9033
9058
|
s(:true)),
|
9034
9059
|
%q{in A[x:] then true},
|
9035
|
-
%q{
|
9060
|
+
%q{ ~~~~~ expression (in_pattern.const_pattern)
|
9036
9061
|
| ~ begin (in_pattern.const_pattern)
|
9037
9062
|
| ~ end (in_pattern.const_pattern)
|
9038
9063
|
| ~ expression (in_pattern.const_pattern.const)
|
@@ -9043,13 +9068,14 @@ class TestParser < Minitest::Test
|
|
9043
9068
|
s(:in_pattern,
|
9044
9069
|
s(:const_pattern,
|
9045
9070
|
s(:const, nil, :A),
|
9046
|
-
|
9071
|
+
s(:array_pattern)),
|
9047
9072
|
nil,
|
9048
9073
|
s(:true)),
|
9049
9074
|
%q{in A[] then true},
|
9050
|
-
%q{
|
9075
|
+
%q{ ~~~ expression (in_pattern.const_pattern)
|
9051
9076
|
| ~ begin (in_pattern.const_pattern)
|
9052
|
-
| ~ end (in_pattern.const_pattern)
|
9077
|
+
| ~ end (in_pattern.const_pattern)
|
9078
|
+
| ~~ expression (in_pattern.const_pattern.array_pattern)}
|
9053
9079
|
)
|
9054
9080
|
end
|
9055
9081
|
|
@@ -9093,6 +9119,20 @@ class TestParser < Minitest::Test
|
|
9093
9119
|
)
|
9094
9120
|
end
|
9095
9121
|
|
9122
|
+
def test_pattern_matching_blank_else
|
9123
|
+
assert_parses(
|
9124
|
+
s(:case_match,
|
9125
|
+
s(:int, 1),
|
9126
|
+
s(:in_pattern,
|
9127
|
+
s(:int, 2), nil,
|
9128
|
+
s(:int, 3)),
|
9129
|
+
s(:empty_else)),
|
9130
|
+
%q{case 1; in 2; 3; else; end},
|
9131
|
+
%q{ ~~~~ else},
|
9132
|
+
SINCE_2_7
|
9133
|
+
)
|
9134
|
+
end
|
9135
|
+
|
9096
9136
|
def assert_pattern_matching_defines_local_variables(match_code, lvar_names, versions = SINCE_2_7)
|
9097
9137
|
code = "case 1; #{match_code}; then [#{lvar_names.join(', ')}]; end"
|
9098
9138
|
|
@@ -9294,4 +9334,24 @@ class TestParser < Minitest::Test
|
|
9294
9334
|
%{ ^^ location},
|
9295
9335
|
SINCE_2_7)
|
9296
9336
|
end
|
9337
|
+
|
9338
|
+
def test_pattern_matching_required_bound_variable_before_pin
|
9339
|
+
assert_diagnoses(
|
9340
|
+
[:error, :undefined_lvar, { :name => 'a' }],
|
9341
|
+
%{case 0; in ^a; true; end},
|
9342
|
+
%{ ^ location},
|
9343
|
+
SINCE_2_7)
|
9344
|
+
end
|
9345
|
+
|
9346
|
+
def test_parser_bug_645
|
9347
|
+
assert_parses(
|
9348
|
+
s(:block,
|
9349
|
+
s(:lambda),
|
9350
|
+
s(:args,
|
9351
|
+
s(:optarg, :arg,
|
9352
|
+
s(:hash))), nil),
|
9353
|
+
'-> (arg={}) {}',
|
9354
|
+
%{},
|
9355
|
+
SINCE_1_9)
|
9356
|
+
end
|
9297
9357
|
end
|
@@ -31,16 +31,16 @@ class TestSourceCommentAssociator < Minitest::Test
|
|
31
31
|
ast, associations = associate(<<-END)
|
32
32
|
#!/usr/bin/env ruby
|
33
33
|
# coding: utf-8
|
34
|
-
# class
|
35
|
-
# another class
|
34
|
+
# class preceding
|
35
|
+
# another class preceding
|
36
36
|
class Foo # class keyword line
|
37
|
-
# method foo
|
37
|
+
# method foo preceding
|
38
38
|
def foo
|
39
39
|
puts 'foo'
|
40
40
|
end # method foo decorating
|
41
|
-
# method bar
|
41
|
+
# method bar preceding
|
42
42
|
def bar
|
43
|
-
# expression
|
43
|
+
# expression preceding
|
44
44
|
1 + # 1 decorating
|
45
45
|
2
|
46
46
|
# method bar sparse
|
@@ -58,8 +58,8 @@ end # class decorating
|
|
58
58
|
|
59
59
|
assert_equal 6, associations.size
|
60
60
|
assert_equal [
|
61
|
-
'# class
|
62
|
-
'# another class
|
61
|
+
'# class preceding',
|
62
|
+
'# another class preceding',
|
63
63
|
'# class sparse',
|
64
64
|
'# class decorating'
|
65
65
|
], associations[klass_node].map(&:text)
|
@@ -67,16 +67,16 @@ end # class decorating
|
|
67
67
|
'# class keyword line'
|
68
68
|
], associations[klass_name_node].map(&:text)
|
69
69
|
assert_equal [
|
70
|
-
'# method foo
|
70
|
+
'# method foo preceding',
|
71
71
|
'# method foo decorating'
|
72
72
|
], associations[foo_node].map(&:text)
|
73
73
|
assert_equal [
|
74
|
-
'# method bar
|
74
|
+
'# method bar preceding',
|
75
75
|
'# method bar sparse',
|
76
76
|
'# method bar decorating'
|
77
77
|
], associations[bar_node].map(&:text)
|
78
78
|
assert_equal [
|
79
|
-
'# expression
|
79
|
+
'# expression preceding'
|
80
80
|
], associations[expr_node].map(&:text)
|
81
81
|
assert_equal [
|
82
82
|
'# 1 decorating'
|
@@ -112,16 +112,16 @@ end
|
|
112
112
|
ast, associations = associate_locations(<<-END)
|
113
113
|
#!/usr/bin/env ruby
|
114
114
|
# coding: utf-8
|
115
|
-
# class
|
116
|
-
# another class
|
115
|
+
# class preceding
|
116
|
+
# another class preceding
|
117
117
|
class Foo # class keyword line
|
118
|
-
# method foo
|
118
|
+
# method foo preceding
|
119
119
|
def foo
|
120
120
|
puts 'foo'
|
121
121
|
end # method foo decorating
|
122
|
-
# method bar
|
122
|
+
# method bar preceding
|
123
123
|
def bar
|
124
|
-
# expression
|
124
|
+
# expression preceding
|
125
125
|
1 + # 1 decorating
|
126
126
|
2
|
127
127
|
# method bar sparse
|
@@ -139,8 +139,8 @@ end # class decorating
|
|
139
139
|
|
140
140
|
assert_equal 6, associations.size
|
141
141
|
assert_equal [
|
142
|
-
'# class
|
143
|
-
'# another class
|
142
|
+
'# class preceding',
|
143
|
+
'# another class preceding',
|
144
144
|
'# class sparse',
|
145
145
|
'# class decorating'
|
146
146
|
], associations[klass_node.loc].map(&:text)
|
@@ -148,16 +148,16 @@ end # class decorating
|
|
148
148
|
'# class keyword line'
|
149
149
|
], associations[klass_name_node.loc].map(&:text)
|
150
150
|
assert_equal [
|
151
|
-
'# method foo
|
151
|
+
'# method foo preceding',
|
152
152
|
'# method foo decorating'
|
153
153
|
], associations[foo_node.loc].map(&:text)
|
154
154
|
assert_equal [
|
155
|
-
'# method bar
|
155
|
+
'# method bar preceding',
|
156
156
|
'# method bar sparse',
|
157
157
|
'# method bar decorating'
|
158
158
|
], associations[bar_node.loc].map(&:text)
|
159
159
|
assert_equal [
|
160
|
-
'# expression
|
160
|
+
'# expression preceding'
|
161
161
|
], associations[expr_node.loc].map(&:text)
|
162
162
|
assert_equal [
|
163
163
|
'# 1 decorating'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: parser
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.7.0.
|
4
|
+
version: 2.7.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- whitequark
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-03-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ast
|
@@ -295,7 +295,11 @@ files:
|
|
295
295
|
homepage: https://github.com/whitequark/parser
|
296
296
|
licenses:
|
297
297
|
- MIT
|
298
|
-
metadata:
|
298
|
+
metadata:
|
299
|
+
bug_tracker_uri: https://github.com/whitequark/parser/issues
|
300
|
+
changelog_uri: https://github.com/whitequark/parser/blob/v2.7.0.5/CHANGELOG.md
|
301
|
+
documentation_uri: https://www.rubydoc.info/gems/parser/2.7.0.5
|
302
|
+
source_code_uri: https://github.com/whitequark/parser/tree/v2.7.0.5
|
299
303
|
post_install_message:
|
300
304
|
rdoc_options: []
|
301
305
|
require_paths:
|
@@ -311,7 +315,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
311
315
|
- !ruby/object:Gem::Version
|
312
316
|
version: '0'
|
313
317
|
requirements: []
|
314
|
-
rubygems_version: 3.0.
|
318
|
+
rubygems_version: 3.0.6
|
315
319
|
signing_key:
|
316
320
|
specification_version: 4
|
317
321
|
summary: A Ruby parser written in pure Ruby.
|