parser 2.7.0.1 → 2.7.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 343568dc3db7c4cb37b68cdef2a241b86e639fea958156014ab0b701b0d04426
4
- data.tar.gz: 320c9f744d2ae76c16efb8e70f021ae35faa8bc89251ff211690085cdf7f2fe3
3
+ metadata.gz: 46184af7a1e0d843e62e720cd7795bb196972603e588eed69f47791b3c799288
4
+ data.tar.gz: 1a9d809fc7443fb09deb3a36ea19ad418ff56119040b14a292c9ed8d112d1f29
5
5
  SHA512:
6
- metadata.gz: dc4f82ed4f56061e57952b794f44d039d456bf43b2e805020233e20569908ce95e788520b2642c33bc2838860a80fe5308959fc3c994bcbc48739ca1ca3aed6a
7
- data.tar.gz: 4b4cc6603bef9ca16925bcb009d0b1ed17c3fb22125a0c2b8eb2ea6c631664cea26e466aa7bacbff9b73040a37341cc107f678edc5f81c22745086b011b46b6a
6
+ metadata.gz: 9a91995ac131a4048976358a7bce1bd09b09893bb0b13fa39f2128c47fb0b1179f830a4adbb766df768bfbd2f89a1c5a5ee437dc1433ccaf5ad2307ff7c09d77
7
+ data.tar.gz: 4fe835bc9fe1ff030d57e9a4d9a4657a0d244db23bac3c117e8f78bfc51d9dc330f51257e04c8ba5ef737d3feab11152db2e1ecde1e8b136d4fcc4f253ed549d
@@ -2,23 +2,17 @@ dist: trusty
2
2
  language: ruby
3
3
  matrix:
4
4
  include:
5
- - name: 2.0.0 / Parser tests
6
- rvm: 2.0.0
7
- script: bundle exec rake test_cov
8
- - name: 2.2.10 / Parser tests
9
- rvm: 2.2.10
10
- script: bundle exec rake test_cov
11
- - name: 2.3.8 / Parser tests
12
- rvm: 2.3.8
13
- script: bundle exec rake test_cov
14
5
  - name: 2.4.9 / Parser tests
15
6
  rvm: 2.4.9
16
7
  script: bundle exec rake test_cov
17
- - name: 2.5.7 / Parser tests
18
- rvm: 2.5.7
8
+ - name: 2.5.8 / Parser tests
9
+ rvm: 2.5.8
19
10
  script: bundle exec rake test_cov
20
- - name: 2.6.5 / Parser tests
21
- rvm: 2.6.5
11
+ - name: 2.6.6 / Parser tests
12
+ rvm: 2.6.6
13
+ script: bundle exec rake test_cov
14
+ - name: 2.7.1 / Parser tests
15
+ rvm: 2.7.1
22
16
  script: bundle exec rake test_cov
23
17
  - name: ruby-head / Parser tests
24
18
  rvm: ruby-head
@@ -29,11 +23,14 @@ matrix:
29
23
  - name: rbx-2 / Parser tests
30
24
  rvm: rbx-2
31
25
  script: bundle exec rake test_cov
32
- - name: 2.5.7 / Rubocop tests
33
- rvm: 2.5.7
26
+ - name: 2.5.8 / Rubocop tests
27
+ rvm: 2.5.8
28
+ script: ./ci/run_rubocop_specs
29
+ - name: 2.6.6 / Rubocop tests
30
+ rvm: 2.6.6
34
31
  script: ./ci/run_rubocop_specs
35
- - name: 2.6.5 / Rubocop tests
36
- rvm: 2.6.5
32
+ - name: 2.7.1 / Rubocop tests
33
+ rvm: 2.7.1
37
34
  script: ./ci/run_rubocop_specs
38
35
  allow_failures:
39
36
  - rvm: ruby-head
@@ -1,9 +1,40 @@
1
1
  Changelog
2
2
  =========
3
3
 
4
- Not released (2019-12-30)
4
+ Not released (2020-04-03)
5
5
  -------------------------
6
6
 
7
+ API modifications:
8
+ * Bump ruby versions to 2.4.10, 2.5.8, 2.6.6, 2.7.1. (#665) (Ilya Bylich)
9
+
10
+ Features implemented:
11
+ * ruby27.y: allow newlines inside braced pattern. (#664) (Ilya Bylich)
12
+ * ruby27.y: Allow trailing comma in hash pattern (#661) (Koichi ITO)
13
+
14
+ v2.7.0.5 (2020-03-20)
15
+ ---------------------
16
+
17
+ Features implemented:
18
+ * ruby27.y: fix array pattern with tail source map (#659) (Vladimir Dementyev)
19
+
20
+ Bugs fixed:
21
+ * builder.rb: fix constant_pattern source map (#660) (Vladimir Dementyev)
22
+
23
+ v2.7.0.4 (2020-03-02)
24
+ ---------------------
25
+
26
+ Bugs fixed:
27
+ * lexer.rl: allow spaces before comments-before-leading-dot. (#654) (Ilya Bylich)
28
+
29
+ v2.7.0.2 (2020-01-08)
30
+ ---------------------
31
+
32
+ Bugs fixed:
33
+ * lexer.rl: fix paren_nest for curly braces (#646) (Ilya Bylich)
34
+
35
+ v2.7.0.1 (2019-12-30)
36
+ ---------------------
37
+
7
38
  Bugs fixed:
8
39
  * dedenter.rb: prevent `ArgumentError` when processing binary en… (#642) (Koichi ITO)
9
40
 
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 = true
28
- Parser::Builders::Default.emit_procarg0 = true
29
- Parser::Builders::Default.emit_encoding = true
30
- Parser::Builders::Default.emit_index = true
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 occuring corner cases, this is not done.
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
 
@@ -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
- ~~~ expression
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
- ~~~~~~~~~~~ expression (const-pattern)
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
- ~~~~~~~~~~~~ expression (const-pattern)
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
  ~~~
@@ -274,6 +274,10 @@ module Parser
274
274
  'Parser::AST::Processor#on_argument instead.'
275
275
  on_argument(node)
276
276
  end
277
+
278
+ def on_empty_else(node)
279
+ node
280
+ end
277
281
  end
278
282
  end
279
283
  end
@@ -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
- elements = elements.map do |element|
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
- n(node_type, elements,
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 ], nil)
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
- collection_map(ldelim_t, [pattern], rdelim_t))
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
- loc = loc(begin_t).join(loc(end_t))
1376
- check_duplicate_pattern_key(var_name, loc)
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)
@@ -48,7 +48,7 @@ module Parser
48
48
  CurrentRuby = Ruby23
49
49
 
50
50
  when /^2\.4\./
51
- current_version = '2.4.9'
51
+ current_version = '2.4.10'
52
52
  if RUBY_VERSION != current_version
53
53
  warn_syntax_deviation 'parser/ruby24', current_version
54
54
  end
@@ -57,7 +57,7 @@ module Parser
57
57
  CurrentRuby = Ruby24
58
58
 
59
59
  when /^2\.5\./
60
- current_version = '2.5.7'
60
+ current_version = '2.5.8'
61
61
  if RUBY_VERSION != current_version
62
62
  warn_syntax_deviation 'parser/ruby25', current_version
63
63
  end
@@ -66,7 +66,7 @@ module Parser
66
66
  CurrentRuby = Ruby25
67
67
 
68
68
  when /^2\.6\./
69
- current_version = '2.6.5'
69
+ current_version = '2.6.6'
70
70
  if RUBY_VERSION != current_version
71
71
  warn_syntax_deviation 'parser/ruby26', current_version
72
72
  end
@@ -75,7 +75,7 @@ module Parser
75
75
  CurrentRuby = Ruby26
76
76
 
77
77
  when /^2\.7\./
78
- current_version = '2.7.0'
78
+ current_version = '2.7.1'
79
79
  if RUBY_VERSION != current_version
80
80
  warn_syntax_deviation 'parser/ruby27', current_version
81
81
  end
@@ -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.
@@ -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
 
@@ -31,6 +31,7 @@ module Parser
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
35
  ).map(&:to_sym).to_set.freeze
35
36
 
36
37
  end # Meta
@@ -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
- result = @builder.const_pattern(val[0], val[1], nil, val[2])
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
- result = @builder.const_pattern(val[0], val[1], nil, val[2])
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
  {
@@ -1875,13 +1877,16 @@ opt_block_args_tail:
1875
1877
  | tLBRACE
1876
1878
  {
1877
1879
  @pattern_hash_keys.push
1880
+ result = @lexer.in_kwarg
1881
+ @lexer.in_kwarg = false
1878
1882
  }
1879
- p_kwargs tRCURLY
1883
+ p_kwargs rbrace
1880
1884
  {
1881
1885
  @pattern_hash_keys.pop
1886
+ @lexer.in_kwarg = val[1]
1882
1887
  result = @builder.hash_pattern(val[0], val[2], val[3])
1883
1888
  }
1884
- | tLBRACE tRCURLY
1889
+ | tLBRACE rbrace
1885
1890
  {
1886
1891
  result = @builder.hash_pattern(val[0], [], val[1])
1887
1892
  }
@@ -1932,7 +1937,7 @@ opt_block_args_tail:
1932
1937
  # array patterns that end with comma
1933
1938
  # like [1, 2,]
1934
1939
  # must be emitted as `array_pattern_with_tail`
1935
- item = @builder.match_with_trailing_comma(val[0])
1940
+ item = @builder.match_with_trailing_comma(val[0], val[1])
1936
1941
  result = [ item ]
1937
1942
  }
1938
1943
  | p_args_head p_arg tCOMMA
@@ -1940,7 +1945,7 @@ opt_block_args_tail:
1940
1945
  # array patterns that end with comma
1941
1946
  # like [1, 2,]
1942
1947
  # must be emitted as `array_pattern_with_tail`
1943
- last_item = @builder.match_with_trailing_comma(val[1])
1948
+ last_item = @builder.match_with_trailing_comma(val[1], val[2])
1944
1949
  result = [ *val[0], last_item ]
1945
1950
  }
1946
1951
 
@@ -1984,6 +1989,10 @@ opt_block_args_tail:
1984
1989
  {
1985
1990
  result = val[0]
1986
1991
  }
1992
+ | p_kwarg tCOMMA
1993
+ {
1994
+ result = val[0]
1995
+ }
1987
1996
  | p_kwrest
1988
1997
  {
1989
1998
  result = val[0]
@@ -2096,6 +2105,11 @@ opt_block_args_tail:
2096
2105
 
2097
2106
  p_var_ref: tCARET tIDENTIFIER
2098
2107
  {
2108
+ name = val[1][0]
2109
+ unless static_env.declared?(name)
2110
+ diagnostic :error, :undefined_lvar, { :name => name }, val[1]
2111
+ end
2112
+
2099
2113
  lvar = @builder.accessible(@builder.ident(val[1]))
2100
2114
  result = @builder.pin(val[0], lvar)
2101
2115
  }
@@ -2891,6 +2905,10 @@ keyword_variable: kNIL
2891
2905
  {
2892
2906
  result = val[1]
2893
2907
  }
2908
+ rbrace: opt_nl tRCURLY
2909
+ {
2910
+ result = val[1]
2911
+ }
2894
2912
  trailer: | tNL | tCOMMA
2895
2913
 
2896
2914
  term: tSEMI
@@ -56,11 +56,11 @@ module Parser
56
56
  if action.range == @range
57
57
  merge(action)
58
58
  else
59
- place_in_hierachy(action)
59
+ place_in_hierarchy(action)
60
60
  end
61
61
  end
62
62
 
63
- def place_in_hierachy(action)
63
+ def place_in_hierarchy(action)
64
64
  family = @children.group_by { |child| child.relationship_with(action) }
65
65
 
66
66
  if family[:fusible]
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Parser
4
- VERSION = '2.7.0.1'
4
+ VERSION = '2.7.1.0'
5
5
  end
@@ -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
@@ -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:
@@ -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{ ~ expression (in_pattern.array_pattern_with_tail)}
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{ ~~~~ expression (in_pattern.array_pattern_with_tail)}
8471
+ %q{ ~~~~~ expression (in_pattern.array_pattern_with_tail)}
8458
8472
  )
8459
8473
 
8460
8474
  assert_parses_pattern_match(
@@ -8661,6 +8675,18 @@ class TestParser < Minitest::Test
8661
8675
  | ~ end (in_pattern.hash_pattern)}
8662
8676
  )
8663
8677
 
8678
+ assert_parses_pattern_match(
8679
+ s(:in_pattern,
8680
+ s(:hash_pattern,
8681
+ s(:pair, s(:sym, :a), s(:int, 1))),
8682
+ nil,
8683
+ s(:true)),
8684
+ %q{in { a: 1, } then true},
8685
+ %q{ ~~~~~~~~~ expression (in_pattern.hash_pattern)
8686
+ | ~ begin (in_pattern.hash_pattern)
8687
+ | ~ end (in_pattern.hash_pattern)}
8688
+ )
8689
+
8664
8690
  assert_parses_pattern_match(
8665
8691
  s(:in_pattern,
8666
8692
  s(:hash_pattern,
@@ -8732,6 +8758,67 @@ class TestParser < Minitest::Test
8732
8758
  %q{in a: 1, _a:, ** then true},
8733
8759
  %q{ ~~~~~~~~~~~~~ expression (in_pattern.hash_pattern)}
8734
8760
  )
8761
+
8762
+ assert_parses_pattern_match(
8763
+ s(:in_pattern,
8764
+ s(:hash_pattern,
8765
+ s(:pair,
8766
+ s(:sym, :a),
8767
+ s(:int, 1))), nil,
8768
+ s(:false)),
8769
+ %q{
8770
+ in {a: 1
8771
+ }
8772
+ false
8773
+ },
8774
+ %q{}
8775
+ )
8776
+
8777
+
8778
+ assert_parses_pattern_match(
8779
+ s(:in_pattern,
8780
+ s(:hash_pattern,
8781
+ s(:pair,
8782
+ s(:sym, :a),
8783
+ s(:int, 2))), nil,
8784
+ s(:false)),
8785
+ %q{
8786
+ in {a:
8787
+ 2}
8788
+ false
8789
+ },
8790
+ %q{}
8791
+ )
8792
+
8793
+ assert_parses_pattern_match(
8794
+ s(:in_pattern,
8795
+ s(:hash_pattern,
8796
+ s(:pair,
8797
+ s(:sym, :a),
8798
+ s(:hash_pattern,
8799
+ s(:match_var, :b))),
8800
+ s(:match_var, :c)), nil,
8801
+ s(:send, nil, :p,
8802
+ s(:lvar, :c))),
8803
+ %q{
8804
+ in a: {b:}, c:
8805
+ p c
8806
+ },
8807
+ %q{}
8808
+ )
8809
+
8810
+ assert_parses_pattern_match(
8811
+ s(:in_pattern,
8812
+ s(:hash_pattern,
8813
+ s(:match_var, :a)), nil,
8814
+ s(:true)),
8815
+ %q{
8816
+ in {a:
8817
+ }
8818
+ true
8819
+ },
8820
+ %q{}
8821
+ )
8735
8822
  end
8736
8823
 
8737
8824
  def test_pattern_matching_hash_with_string_keys
@@ -8839,6 +8926,15 @@ class TestParser < Minitest::Test
8839
8926
  )
8840
8927
  end
8841
8928
 
8929
+ def test_pattern_matching_hash_with_string_interpolation_keys
8930
+ assert_diagnoses(
8931
+ [:error, :pm_interp_in_var_name],
8932
+ %q{case a; in "#{a}": 1; end},
8933
+ %q{ ~~~~~~~ location},
8934
+ SINCE_2_7
8935
+ )
8936
+ end
8937
+
8842
8938
  def test_pattern_matching_keyword_variable
8843
8939
  assert_parses_pattern_match(
8844
8940
  s(:in_pattern,
@@ -8970,7 +9066,7 @@ class TestParser < Minitest::Test
8970
9066
  nil,
8971
9067
  s(:true)),
8972
9068
  %q{in A(1, 2) then true},
8973
- %q{ ~~~~~~ expression (in_pattern.const_pattern)
9069
+ %q{ ~~~~~~~ expression (in_pattern.const_pattern)
8974
9070
  | ~ begin (in_pattern.const_pattern)
8975
9071
  | ~ end (in_pattern.const_pattern)
8976
9072
  | ~ expression (in_pattern.const_pattern.const)
@@ -8986,7 +9082,7 @@ class TestParser < Minitest::Test
8986
9082
  nil,
8987
9083
  s(:true)),
8988
9084
  %q{in A(x:) then true},
8989
- %q{ ~~~~ expression (in_pattern.const_pattern)
9085
+ %q{ ~~~~~ expression (in_pattern.const_pattern)
8990
9086
  | ~ begin (in_pattern.const_pattern)
8991
9087
  | ~ end (in_pattern.const_pattern)
8992
9088
  | ~ expression (in_pattern.const_pattern.const)
@@ -8997,13 +9093,15 @@ class TestParser < Minitest::Test
8997
9093
  s(:in_pattern,
8998
9094
  s(:const_pattern,
8999
9095
  s(:const, nil, :A),
9000
- nil),
9096
+ s(:array_pattern)),
9001
9097
  nil,
9002
9098
  s(:true)),
9003
9099
  %q{in A() then true},
9004
- %q{ ~~ expression (in_pattern.const_pattern)
9100
+ %q{ ~~~ expression (in_pattern.const_pattern)
9005
9101
  | ~ begin (in_pattern.const_pattern)
9006
- | ~ end (in_pattern.const_pattern)}
9102
+ | ~ end (in_pattern.const_pattern)
9103
+ | ~ expression (in_pattern.const_pattern.const)
9104
+ | ~~ expression (in_pattern.const_pattern.array_pattern)}
9007
9105
  )
9008
9106
 
9009
9107
  assert_parses_pattern_match(
@@ -9016,7 +9114,7 @@ class TestParser < Minitest::Test
9016
9114
  nil,
9017
9115
  s(:true)),
9018
9116
  %q{in A[1, 2] then true},
9019
- %q{ ~~~~~~ expression (in_pattern.const_pattern)
9117
+ %q{ ~~~~~~~ expression (in_pattern.const_pattern)
9020
9118
  | ~ begin (in_pattern.const_pattern)
9021
9119
  | ~ end (in_pattern.const_pattern)
9022
9120
  | ~ expression (in_pattern.const_pattern.const)
@@ -9032,7 +9130,7 @@ class TestParser < Minitest::Test
9032
9130
  nil,
9033
9131
  s(:true)),
9034
9132
  %q{in A[x:] then true},
9035
- %q{ ~~~~ expression (in_pattern.const_pattern)
9133
+ %q{ ~~~~~ expression (in_pattern.const_pattern)
9036
9134
  | ~ begin (in_pattern.const_pattern)
9037
9135
  | ~ end (in_pattern.const_pattern)
9038
9136
  | ~ expression (in_pattern.const_pattern.const)
@@ -9043,13 +9141,14 @@ class TestParser < Minitest::Test
9043
9141
  s(:in_pattern,
9044
9142
  s(:const_pattern,
9045
9143
  s(:const, nil, :A),
9046
- nil),
9144
+ s(:array_pattern)),
9047
9145
  nil,
9048
9146
  s(:true)),
9049
9147
  %q{in A[] then true},
9050
- %q{ ~~ expression (in_pattern.const_pattern)
9148
+ %q{ ~~~ expression (in_pattern.const_pattern)
9051
9149
  | ~ begin (in_pattern.const_pattern)
9052
- | ~ end (in_pattern.const_pattern)}
9150
+ | ~ end (in_pattern.const_pattern)
9151
+ | ~~ expression (in_pattern.const_pattern.array_pattern)}
9053
9152
  )
9054
9153
  end
9055
9154
 
@@ -9093,6 +9192,20 @@ class TestParser < Minitest::Test
9093
9192
  )
9094
9193
  end
9095
9194
 
9195
+ def test_pattern_matching_blank_else
9196
+ assert_parses(
9197
+ s(:case_match,
9198
+ s(:int, 1),
9199
+ s(:in_pattern,
9200
+ s(:int, 2), nil,
9201
+ s(:int, 3)),
9202
+ s(:empty_else)),
9203
+ %q{case 1; in 2; 3; else; end},
9204
+ %q{ ~~~~ else},
9205
+ SINCE_2_7
9206
+ )
9207
+ end
9208
+
9096
9209
  def assert_pattern_matching_defines_local_variables(match_code, lvar_names, versions = SINCE_2_7)
9097
9210
  code = "case 1; #{match_code}; then [#{lvar_names.join(', ')}]; end"
9098
9211
 
@@ -9294,4 +9407,24 @@ class TestParser < Minitest::Test
9294
9407
  %{ ^^ location},
9295
9408
  SINCE_2_7)
9296
9409
  end
9410
+
9411
+ def test_pattern_matching_required_bound_variable_before_pin
9412
+ assert_diagnoses(
9413
+ [:error, :undefined_lvar, { :name => 'a' }],
9414
+ %{case 0; in ^a; true; end},
9415
+ %{ ^ location},
9416
+ SINCE_2_7)
9417
+ end
9418
+
9419
+ def test_parser_bug_645
9420
+ assert_parses(
9421
+ s(:block,
9422
+ s(:lambda),
9423
+ s(:args,
9424
+ s(:optarg, :arg,
9425
+ s(:hash))), nil),
9426
+ '-> (arg={}) {}',
9427
+ %{},
9428
+ SINCE_1_9)
9429
+ end
9297
9430
  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 preceeding
35
- # another class preceeding
34
+ # class preceding
35
+ # another class preceding
36
36
  class Foo # class keyword line
37
- # method foo preceeding
37
+ # method foo preceding
38
38
  def foo
39
39
  puts 'foo'
40
40
  end # method foo decorating
41
- # method bar preceeding
41
+ # method bar preceding
42
42
  def bar
43
- # expression preceeding
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 preceeding',
62
- '# another class preceeding',
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 preceeding',
70
+ '# method foo preceding',
71
71
  '# method foo decorating'
72
72
  ], associations[foo_node].map(&:text)
73
73
  assert_equal [
74
- '# method bar preceeding',
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 preceeding'
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 preceeding
116
- # another class preceeding
115
+ # class preceding
116
+ # another class preceding
117
117
  class Foo # class keyword line
118
- # method foo preceeding
118
+ # method foo preceding
119
119
  def foo
120
120
  puts 'foo'
121
121
  end # method foo decorating
122
- # method bar preceeding
122
+ # method bar preceding
123
123
  def bar
124
- # expression preceeding
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 preceeding',
143
- '# another class preceeding',
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 preceeding',
151
+ '# method foo preceding',
152
152
  '# method foo decorating'
153
153
  ], associations[foo_node.loc].map(&:text)
154
154
  assert_equal [
155
- '# method bar preceeding',
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 preceeding'
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.1
4
+ version: 2.7.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - whitequark
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-12-30 00:00:00.000000000 Z
11
+ date: 2020-04-03 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.1.0/CHANGELOG.md
301
+ documentation_uri: https://www.rubydoc.info/gems/parser/2.7.1.0
302
+ source_code_uri: https://github.com/whitequark/parser/tree/v2.7.1.0
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.1
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.