parser 2.5.0.0 → 2.5.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +17 -2
- data/README.md +3 -1
- data/Rakefile +1 -1
- data/doc/AST_FORMAT.md +52 -12
- data/lib/parser.rb +1 -0
- data/lib/parser/builders/default.rb +77 -12
- data/lib/parser/current.rb +3 -3
- data/lib/parser/lexer.rl +8 -4
- data/lib/parser/meta.rb +1 -1
- data/lib/parser/ruby24.y +23 -2
- data/lib/parser/ruby25.y +55 -40
- data/lib/parser/source/buffer.rb +3 -1
- data/lib/parser/source/map/index.rb +33 -0
- data/lib/parser/version.rb +1 -1
- data/test/test_encoding.rb +8 -0
- data/test/test_parser.rb +223 -25
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9ee63d086cc3d7ade55f51e03ac92d6f88315fb7
|
4
|
+
data.tar.gz: 8efdd495d4866bfb27db7b0b15be94515b18a91f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ae6472a338db72f9d422633eeb83fb6ba37f3f07e99f89d8d2661b840a08177aaffb2ffa8677a7d826f86278c94ba2434b68e00e265d43e7da3ca4998fceeb49
|
7
|
+
data.tar.gz: 382b2d934d537bf496e74911a25a7caf286192955a50698f4a0c7b80d5b0f852feebd51d6beb0cd12381052960ab0c4687e26e965a43cab36269ec9919bf730e
|
data/CHANGELOG.md
CHANGED
@@ -1,8 +1,23 @@
|
|
1
1
|
Changelog
|
2
2
|
=========
|
3
3
|
|
4
|
-
|
5
|
-
|
4
|
+
v2.5.0.1 (2018-02-21)
|
5
|
+
---------------------
|
6
|
+
|
7
|
+
Features implemented:
|
8
|
+
* builders/default: __ENCODING__: emit as s(:__ENCODING__) via AST opt-in. (whitequark)
|
9
|
+
* ruby25.y: Extract expr_value_do rule. This commit tracks upstream commit ruby/ruby@508533f. (Ilya Bylich)
|
10
|
+
* ruby25.y: Extract begin_block rule. This commit tracks upstream commit ruby/ruby@762d23c. (Ilya Bylich)
|
11
|
+
* ruby25.y: Allow class and method definition in the while condition. (#432) (Ilya Bylich)
|
12
|
+
* ruby25: Allow `-> do rescue; end`. (#431) (Ilya Bylich)
|
13
|
+
|
14
|
+
Bugs fixed:
|
15
|
+
* parser/current: latest released Ruby series is 2.5.x. (whitequark)
|
16
|
+
* builders/default: x[], x[]=1: emit as s(:index), s(:indexasgn) via AST opt-in. (whitequark)
|
17
|
+
* lexer.rl: "#{-> foo {}}": fix parsing of interpolated lambda with open args. (Ilya Bylich)
|
18
|
+
|
19
|
+
v2.5.0.0 (2018-02-16)
|
20
|
+
---------------------
|
6
21
|
|
7
22
|
API modifications:
|
8
23
|
* Parser::Current: bump to 2.2.9 and 2.3.6. (Stan Hu)
|
data/README.md
CHANGED
@@ -24,8 +24,10 @@ 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
|
27
|
+
Parser::Builders::Default.emit_lambda = true
|
28
28
|
Parser::Builders::Default.emit_procarg0 = true
|
29
|
+
Parser::Builders::Default.emit_encoding = true
|
30
|
+
Parser::Builders::Default.emit_index = true
|
29
31
|
|
30
32
|
Parse a chunk of code:
|
31
33
|
|
data/Rakefile
CHANGED
@@ -104,7 +104,7 @@ task :changelog do
|
|
104
104
|
|
105
105
|
current_version = "#{$1} (#{date})" if version =~ /(v[\d\w.]+)/
|
106
106
|
current_version = "Not released (#{date})" \
|
107
|
-
if version =~ /(^| |\/)#{Regexp.escape branch}$/
|
107
|
+
if version =~ /(^| |\/)#{Regexp.escape branch}$/ && !branch.start_with?('v')
|
108
108
|
|
109
109
|
next if current_version.nil?
|
110
110
|
changelog[current_version] # add a hash
|
data/doc/AST_FORMAT.md
CHANGED
@@ -1081,18 +1081,6 @@ Format:
|
|
1081
1081
|
~ selector
|
1082
1082
|
^ operator
|
1083
1083
|
~~~~~~~~~ expression
|
1084
|
-
|
1085
|
-
(send (lvar :foo) :[] (int 1))
|
1086
|
-
"foo[i]"
|
1087
|
-
~~~ selector
|
1088
|
-
~~~~~~ expression
|
1089
|
-
|
1090
|
-
(send (lvar :bar) :[]= (int 1) (int 2) (lvar :baz))
|
1091
|
-
"bar[1, 2] = baz"
|
1092
|
-
~~~~~~ selector
|
1093
|
-
^ operator
|
1094
|
-
~~~~~~~~~~~~~~~ expression
|
1095
|
-
|
1096
1084
|
~~~
|
1097
1085
|
|
1098
1086
|
### To superclass
|
@@ -1135,6 +1123,26 @@ Format:
|
|
1135
1123
|
~~~~~~~~~~ expression
|
1136
1124
|
~~~
|
1137
1125
|
|
1126
|
+
### Indexing
|
1127
|
+
|
1128
|
+
Format:
|
1129
|
+
|
1130
|
+
~~~
|
1131
|
+
(index (lvar :foo) (int 1))
|
1132
|
+
"foo[1]"
|
1133
|
+
^ begin
|
1134
|
+
^ end
|
1135
|
+
~~~~~~ expression
|
1136
|
+
|
1137
|
+
(indexasgn (lvar :bar) (int 1) (int 2) (lvar :baz))
|
1138
|
+
"bar[1, 2] = baz"
|
1139
|
+
^ begin
|
1140
|
+
^ end
|
1141
|
+
^ operator
|
1142
|
+
~~~~~~~~~~~~~~~ expression
|
1143
|
+
|
1144
|
+
~~~
|
1145
|
+
|
1138
1146
|
### Passing a literal block
|
1139
1147
|
|
1140
1148
|
~~~
|
@@ -1676,3 +1684,35 @@ Format:
|
|
1676
1684
|
~~ selector
|
1677
1685
|
~~~~~~~~~~~~~~~~~~~~~~ expression
|
1678
1686
|
~~~
|
1687
|
+
|
1688
|
+
## Special constants
|
1689
|
+
|
1690
|
+
### File
|
1691
|
+
|
1692
|
+
Format:
|
1693
|
+
|
1694
|
+
~~~
|
1695
|
+
(__FILE__)
|
1696
|
+
"__FILE__"
|
1697
|
+
~~~~~~~~ expression
|
1698
|
+
~~~
|
1699
|
+
|
1700
|
+
### Line
|
1701
|
+
|
1702
|
+
Format:
|
1703
|
+
|
1704
|
+
~~~
|
1705
|
+
(__LINE__)
|
1706
|
+
"__LINE__"
|
1707
|
+
~~~~~~~~ expression
|
1708
|
+
~~~
|
1709
|
+
|
1710
|
+
### Encoding
|
1711
|
+
|
1712
|
+
Format:
|
1713
|
+
|
1714
|
+
~~~
|
1715
|
+
(__ENCODING__)
|
1716
|
+
"__ENCODING__"
|
1717
|
+
~~~~~~~~~~~~ expression
|
1718
|
+
~~~
|
data/lib/parser.rb
CHANGED
@@ -47,6 +47,7 @@ module Parser
|
|
47
47
|
require 'parser/source/map/keyword'
|
48
48
|
require 'parser/source/map/definition'
|
49
49
|
require 'parser/source/map/send'
|
50
|
+
require 'parser/source/map/index'
|
50
51
|
require 'parser/source/map/condition'
|
51
52
|
require 'parser/source/map/ternary'
|
52
53
|
require 'parser/source/map/for'
|
@@ -31,10 +31,10 @@ module Parser
|
|
31
31
|
# all new code should set this attribute to true.
|
32
32
|
#
|
33
33
|
# If set to false (the default), arguments of `m { |a| }` are emitted as
|
34
|
-
# `s(:args, s(:arg, :a))
|
34
|
+
# `s(:args, s(:arg, :a))`.
|
35
35
|
#
|
36
36
|
# If set to true, arguments of `m { |a| }` are emitted as
|
37
|
-
# `s(:args, s(:procarg0, :a))
|
37
|
+
# `s(:args, s(:procarg0, :a)).
|
38
38
|
#
|
39
39
|
# @return [Boolean]
|
40
40
|
attr_accessor :emit_procarg0
|
@@ -42,12 +42,54 @@ module Parser
|
|
42
42
|
|
43
43
|
@emit_procarg0 = false
|
44
44
|
|
45
|
+
class << self
|
46
|
+
##
|
47
|
+
# AST compatibility attribute; locations of `__ENCODING__` are not the same
|
48
|
+
# as locations of `Encoding::UTF_8` causing problems during rewriting,
|
49
|
+
# all new code should set this attribute to true.
|
50
|
+
#
|
51
|
+
# If set to false (the default), `__ENCODING__` is emitted as
|
52
|
+
# ` s(:const, s(:const, nil, :Encoding), :UTF_8)`.
|
53
|
+
#
|
54
|
+
# If set to true, `__ENCODING__` is emitted as
|
55
|
+
# `s(:__ENCODING__)`.
|
56
|
+
#
|
57
|
+
# @return [Boolean]
|
58
|
+
attr_accessor :emit_encoding
|
59
|
+
end
|
60
|
+
|
61
|
+
@emit_encoding = false
|
62
|
+
|
63
|
+
class << self
|
64
|
+
##
|
65
|
+
# AST compatibility attribute; indexed assignment, `x[] = 1`, is not
|
66
|
+
# semantically equivalent to calling the method directly, `x.[]=(1)`.
|
67
|
+
# Specifically, in the former case, the expression's value is always 1,
|
68
|
+
# and in the latter case, the expression's value is the return value
|
69
|
+
# of the `[]=` method.
|
70
|
+
#
|
71
|
+
# If set to false (the default), `self[1]` is emitted as
|
72
|
+
# `s(:send, s(:self), :[], s(:int, 1))`, and `self[1] = 2` is
|
73
|
+
# emitted as `s(:send, s(:self), :[]=, s(:int, 1), s(:int, 2))`.
|
74
|
+
#
|
75
|
+
# If set to true, `self[1]` is emitted as
|
76
|
+
# `s(:index, s(:self), s(:int, 1))`, and `self[1] = 2` is
|
77
|
+
# emitted as `s(:indexasgn, s(:self), s(:int, 1), s(:int, 2))`.
|
78
|
+
#
|
79
|
+
# @return [Boolean]
|
80
|
+
attr_accessor :emit_index
|
81
|
+
end
|
82
|
+
|
83
|
+
@emit_index = false
|
84
|
+
|
45
85
|
class << self
|
46
86
|
##
|
47
87
|
# @api private
|
48
88
|
def modernize
|
49
89
|
@emit_lambda = true
|
50
90
|
@emit_procarg0 = true
|
91
|
+
@emit_encoding = true
|
92
|
+
@emit_index = true
|
51
93
|
end
|
52
94
|
end
|
53
95
|
|
@@ -56,7 +98,7 @@ module Parser
|
|
56
98
|
attr_accessor :parser
|
57
99
|
|
58
100
|
##
|
59
|
-
# If set to true, `__FILE__` and `__LINE__` are transformed to
|
101
|
+
# If set to true (the default), `__FILE__` and `__LINE__` are transformed to
|
60
102
|
# literal nodes. For example, `s(:str, "lib/foo.rb")` and `s(:int, 10)`.
|
61
103
|
#
|
62
104
|
# If set to false, `__FILE__` and `__LINE__` are emitted as-is,
|
@@ -424,8 +466,12 @@ module Parser
|
|
424
466
|
end
|
425
467
|
|
426
468
|
when :__ENCODING__
|
427
|
-
|
428
|
-
|
469
|
+
if !self.class.emit_encoding
|
470
|
+
n(:const, [ n(:const, [ nil, :Encoding], nil), :UTF_8 ],
|
471
|
+
node.loc.dup)
|
472
|
+
else
|
473
|
+
node
|
474
|
+
end
|
429
475
|
|
430
476
|
when :ident
|
431
477
|
name, = *node
|
@@ -515,12 +561,16 @@ module Parser
|
|
515
561
|
|
516
562
|
def op_assign(lhs, op_t, rhs)
|
517
563
|
case lhs.type
|
518
|
-
when :gvasgn, :ivasgn, :lvasgn, :cvasgn, :casgn, :send, :csend
|
564
|
+
when :gvasgn, :ivasgn, :lvasgn, :cvasgn, :casgn, :send, :csend, :index
|
519
565
|
operator = value(op_t)[0..-1].to_sym
|
520
566
|
source_map = lhs.loc.
|
521
567
|
with_operator(loc(op_t)).
|
522
568
|
with_expression(join_exprs(lhs, rhs))
|
523
569
|
|
570
|
+
if lhs.type == :index
|
571
|
+
lhs = lhs.updated(:indexasgn)
|
572
|
+
end
|
573
|
+
|
524
574
|
case operator
|
525
575
|
when :'&&'
|
526
576
|
n(:and_asgn, [ lhs, rhs ], source_map)
|
@@ -785,7 +835,7 @@ module Parser
|
|
785
835
|
diagnostic :error, :block_and_blockarg, nil, last_arg.loc.expression, [loc(begin_t)]
|
786
836
|
end
|
787
837
|
|
788
|
-
if [:send, :csend, :super, :zsuper, :lambda].include?(method_call.type)
|
838
|
+
if [:send, :csend, :index, :super, :zsuper, :lambda].include?(method_call.type)
|
789
839
|
n(:block, [ method_call, args, body ],
|
790
840
|
block_map(method_call.loc.expression, begin_t, end_t))
|
791
841
|
else
|
@@ -825,14 +875,24 @@ module Parser
|
|
825
875
|
end
|
826
876
|
|
827
877
|
def index(receiver, lbrack_t, indexes, rbrack_t)
|
828
|
-
|
829
|
-
|
878
|
+
if self.class.emit_index
|
879
|
+
n(:index, [ receiver, *indexes ],
|
880
|
+
index_map(receiver, lbrack_t, rbrack_t))
|
881
|
+
else
|
882
|
+
n(:send, [ receiver, :[], *indexes ],
|
883
|
+
send_index_map(receiver, lbrack_t, rbrack_t))
|
884
|
+
end
|
830
885
|
end
|
831
886
|
|
832
887
|
def index_asgn(receiver, lbrack_t, indexes, rbrack_t)
|
833
|
-
|
834
|
-
|
835
|
-
|
888
|
+
if self.class.emit_index
|
889
|
+
n(:indexasgn, [ receiver, *indexes ],
|
890
|
+
index_map(receiver, lbrack_t, rbrack_t))
|
891
|
+
else
|
892
|
+
# Incomplete method call.
|
893
|
+
n(:send, [ receiver, :[]=, *indexes ],
|
894
|
+
send_index_map(receiver, lbrack_t, rbrack_t))
|
895
|
+
end
|
836
896
|
end
|
837
897
|
|
838
898
|
def binary_op(receiver, operator_t, arg)
|
@@ -1411,6 +1471,11 @@ module Parser
|
|
1411
1471
|
expr_l)
|
1412
1472
|
end
|
1413
1473
|
|
1474
|
+
def index_map(receiver_e, lbrack_t, rbrack_t)
|
1475
|
+
Source::Map::Index.new(loc(lbrack_t), loc(rbrack_t),
|
1476
|
+
receiver_e.loc.expression.join(loc(rbrack_t)))
|
1477
|
+
end
|
1478
|
+
|
1414
1479
|
def send_index_map(receiver_e, lbrack_t, rbrack_t)
|
1415
1480
|
Source::Map::Send.new(nil, loc(lbrack_t).join(loc(rbrack_t)),
|
1416
1481
|
nil, nil,
|
data/lib/parser/current.rb
CHANGED
@@ -67,8 +67,8 @@ module Parser
|
|
67
67
|
|
68
68
|
else # :nocov:
|
69
69
|
# Keep this in sync with released Ruby.
|
70
|
-
warn_syntax_deviation 'parser/
|
71
|
-
require 'parser/
|
72
|
-
CurrentRuby =
|
70
|
+
warn_syntax_deviation 'parser/ruby25', '2.5.x'
|
71
|
+
require 'parser/ruby25'
|
72
|
+
CurrentRuby = Ruby25
|
73
73
|
end
|
74
74
|
end
|
data/lib/parser/lexer.rl
CHANGED
@@ -89,7 +89,7 @@ class Parser::Lexer
|
|
89
89
|
|
90
90
|
REGEXP_META_CHARACTERS = Regexp.union(*"\\$()*+.<>?[]^{|}".chars).freeze
|
91
91
|
|
92
|
-
attr_reader :source_buffer
|
92
|
+
attr_reader :source_buffer, :last_token
|
93
93
|
|
94
94
|
attr_accessor :diagnostics
|
95
95
|
attr_accessor :static_env
|
@@ -175,6 +175,9 @@ class Parser::Lexer
|
|
175
175
|
|
176
176
|
# State before =begin / =end block comment
|
177
177
|
@cs_before_block_comment = self.class.lex_en_line_begin
|
178
|
+
|
179
|
+
# Last emitted token
|
180
|
+
@last_token = nil
|
178
181
|
end
|
179
182
|
|
180
183
|
def source_buffer=(source_buffer)
|
@@ -325,6 +328,7 @@ class Parser::Lexer
|
|
325
328
|
token = [ type, [ value, range(s, e) ] ]
|
326
329
|
|
327
330
|
@token_queue.push(token)
|
331
|
+
@last_token = token
|
328
332
|
|
329
333
|
@tokens.push(token) if @tokens
|
330
334
|
|
@@ -1433,12 +1437,12 @@ class Parser::Lexer
|
|
1433
1437
|
w_space* e_lbrace
|
1434
1438
|
=> {
|
1435
1439
|
if @lambda_stack.last == @paren_nest
|
1436
|
-
|
1437
|
-
|
1440
|
+
@lambda_stack.pop
|
1441
|
+
emit(:tLAMBEG, '{'.freeze, @te - 1, @te)
|
1438
1442
|
else
|
1439
1443
|
emit(:tLCURLY, '{'.freeze, @te - 1, @te)
|
1440
|
-
fnext expr_value; fbreak;
|
1441
1444
|
end
|
1445
|
+
fnext expr_value; fbreak;
|
1442
1446
|
};
|
1443
1447
|
|
1444
1448
|
#
|
data/lib/parser/meta.rb
CHANGED
@@ -22,7 +22,7 @@ module Parser
|
|
22
22
|
and not or if when case while until while_post
|
23
23
|
until_post for break next redo return resbody
|
24
24
|
kwbegin begin retry preexe postexe iflipflop eflipflop
|
25
|
-
shadowarg complex rational __FILE__ __LINE__
|
25
|
+
shadowarg complex rational __FILE__ __LINE__ __ENCODING__
|
26
26
|
).map(&:to_sym).to_set.freeze
|
27
27
|
|
28
28
|
end # Meta
|
data/lib/parser/ruby24.y
CHANGED
@@ -850,7 +850,28 @@ rule
|
|
850
850
|
}
|
851
851
|
|
852
852
|
command_args: {
|
853
|
-
|
853
|
+
# When branch gets invoked by RACC's lookahead
|
854
|
+
# and command args start with '[' or '('
|
855
|
+
# we need to put `true` to the cmdarg stack
|
856
|
+
# **before** `false` pushed by lexer
|
857
|
+
# m [], n
|
858
|
+
# ^
|
859
|
+
# Right here we have cmdarg [...0] because
|
860
|
+
# lexer pushed it on '['
|
861
|
+
# We need to modify cmdarg stack to [...10]
|
862
|
+
#
|
863
|
+
# For all other cases (like `m n` or `m n, []`) we simply put 1 to the stack
|
864
|
+
# and later lexer pushes corresponding bits on top of it.
|
865
|
+
last_token = @lexer.last_token[0]
|
866
|
+
lookahead = last_token == :tLBRACK || last_token == :tLPAREN_ARG
|
867
|
+
|
868
|
+
if lookahead
|
869
|
+
top = @lexer.cmdarg.pop
|
870
|
+
@lexer.cmdarg.push(true)
|
871
|
+
@lexer.cmdarg.push(top)
|
872
|
+
else
|
873
|
+
@lexer.cmdarg.push(true)
|
874
|
+
end
|
854
875
|
}
|
855
876
|
call_args
|
856
877
|
{
|
@@ -1836,7 +1857,7 @@ regexp_contents: # nothing
|
|
1836
1857
|
}
|
1837
1858
|
compstmt tSTRING_DEND
|
1838
1859
|
{
|
1839
|
-
@lexer.cond.
|
1860
|
+
@lexer.cond.pop
|
1840
1861
|
@lexer.cmdarg.pop
|
1841
1862
|
|
1842
1863
|
result = @builder.begin(val[0], val[2], val[3])
|
data/lib/parser/ruby25.y
CHANGED
@@ -71,9 +71,14 @@ rule
|
|
71
71
|
}
|
72
72
|
|
73
73
|
top_stmt: stmt
|
74
|
-
| klBEGIN
|
74
|
+
| klBEGIN begin_block
|
75
75
|
{
|
76
|
-
result = @builder.preexe(val[0], val[1]
|
76
|
+
result = @builder.preexe(val[0], *val[1])
|
77
|
+
}
|
78
|
+
|
79
|
+
begin_block: tLCURLY top_compstmt tRCURLY
|
80
|
+
{
|
81
|
+
result = val
|
77
82
|
}
|
78
83
|
|
79
84
|
bodystmt: compstmt opt_rescue opt_else opt_ensure
|
@@ -115,7 +120,7 @@ rule
|
|
115
120
|
}
|
116
121
|
|
117
122
|
stmt_or_begin: stmt
|
118
|
-
| klBEGIN
|
123
|
+
| klBEGIN begin_block
|
119
124
|
{
|
120
125
|
diagnostic :error, :begin_in_method, nil, val[0]
|
121
126
|
}
|
@@ -273,6 +278,15 @@ rule
|
|
273
278
|
|
274
279
|
expr_value: expr
|
275
280
|
|
281
|
+
expr_value_do: {
|
282
|
+
@lexer.cond.push(true)
|
283
|
+
}
|
284
|
+
expr_value do
|
285
|
+
{
|
286
|
+
@lexer.cond.pop
|
287
|
+
result = [ val[1], val[2] ]
|
288
|
+
}
|
289
|
+
|
276
290
|
command_call: command
|
277
291
|
| block_command
|
278
292
|
|
@@ -846,7 +860,28 @@ rule
|
|
846
860
|
}
|
847
861
|
|
848
862
|
command_args: {
|
849
|
-
|
863
|
+
# When branch gets invoked by RACC's lookahead
|
864
|
+
# and command args start with '[' or '('
|
865
|
+
# we need to put `true` to the cmdarg stack
|
866
|
+
# **before** `false` pushed by lexer
|
867
|
+
# m [], n
|
868
|
+
# ^
|
869
|
+
# Right here we have cmdarg [...0] because
|
870
|
+
# lexer pushed it on '['
|
871
|
+
# We need to modify cmdarg stack to [...10]
|
872
|
+
#
|
873
|
+
# For all other cases (like `m n` or `m n, []`) we simply put 1 to the stack
|
874
|
+
# and later lexer pushes corresponding bits on top of it.
|
875
|
+
last_token = @lexer.last_token[0]
|
876
|
+
lookahead = last_token == :tLBRACK || last_token == :tLPAREN_ARG
|
877
|
+
|
878
|
+
if lookahead
|
879
|
+
top = @lexer.cmdarg.pop
|
880
|
+
@lexer.cmdarg.push(true)
|
881
|
+
@lexer.cmdarg.push(top)
|
882
|
+
else
|
883
|
+
@lexer.cmdarg.push(true)
|
884
|
+
end
|
850
885
|
}
|
851
886
|
call_args
|
852
887
|
{
|
@@ -1039,31 +1074,13 @@ rule
|
|
1039
1074
|
else_, else_t,
|
1040
1075
|
val[3], val[5])
|
1041
1076
|
}
|
1042
|
-
| kWHILE
|
1077
|
+
| kWHILE expr_value_do compstmt kEND
|
1043
1078
|
{
|
1044
|
-
@
|
1045
|
-
}
|
1046
|
-
expr_value do
|
1047
|
-
{
|
1048
|
-
@lexer.cond.pop
|
1079
|
+
result = @builder.loop(:while, val[0], *val[1], val[2], val[3])
|
1049
1080
|
}
|
1050
|
-
|
1081
|
+
| kUNTIL expr_value_do compstmt kEND
|
1051
1082
|
{
|
1052
|
-
result = @builder.loop(:
|
1053
|
-
val[5], val[6])
|
1054
|
-
}
|
1055
|
-
| kUNTIL
|
1056
|
-
{
|
1057
|
-
@lexer.cond.push(true)
|
1058
|
-
}
|
1059
|
-
expr_value do
|
1060
|
-
{
|
1061
|
-
@lexer.cond.pop
|
1062
|
-
}
|
1063
|
-
compstmt kEND
|
1064
|
-
{
|
1065
|
-
result = @builder.loop(:until, val[0], val[2], val[3],
|
1066
|
-
val[5], val[6])
|
1083
|
+
result = @builder.loop(:until, val[0], *val[1], val[2], val[3])
|
1067
1084
|
}
|
1068
1085
|
| kCASE expr_value opt_terms case_body kEND
|
1069
1086
|
{
|
@@ -1081,24 +1098,15 @@ rule
|
|
1081
1098
|
when_bodies, else_t, else_body,
|
1082
1099
|
val[3])
|
1083
1100
|
}
|
1084
|
-
| kFOR for_var kIN
|
1085
|
-
{
|
1086
|
-
@lexer.cond.push(true)
|
1087
|
-
}
|
1088
|
-
expr_value do
|
1101
|
+
| kFOR for_var kIN expr_value_do compstmt kEND
|
1089
1102
|
{
|
1090
|
-
@
|
1091
|
-
}
|
1092
|
-
compstmt kEND
|
1093
|
-
{
|
1094
|
-
result = @builder.for(val[0], val[1],
|
1095
|
-
val[2], val[4],
|
1096
|
-
val[5], val[7], val[8])
|
1103
|
+
result = @builder.for(val[0], val[1], val[2], *val[3], val[4], val[5])
|
1097
1104
|
}
|
1098
1105
|
| kCLASS cpath superclass
|
1099
1106
|
{
|
1100
1107
|
@static_env.extend_static
|
1101
1108
|
@lexer.push_cmdarg
|
1109
|
+
@lexer.push_cond
|
1102
1110
|
@context.push(:class)
|
1103
1111
|
}
|
1104
1112
|
bodystmt kEND
|
@@ -1113,6 +1121,7 @@ rule
|
|
1113
1121
|
val[4], val[5])
|
1114
1122
|
|
1115
1123
|
@lexer.pop_cmdarg
|
1124
|
+
@lexer.pop_cond
|
1116
1125
|
@static_env.unextend
|
1117
1126
|
@context.pop
|
1118
1127
|
}
|
@@ -1120,6 +1129,7 @@ rule
|
|
1120
1129
|
{
|
1121
1130
|
@static_env.extend_static
|
1122
1131
|
@lexer.push_cmdarg
|
1132
|
+
@lexer.push_cond
|
1123
1133
|
@context.push(:sclass)
|
1124
1134
|
}
|
1125
1135
|
bodystmt kEND
|
@@ -1128,6 +1138,7 @@ rule
|
|
1128
1138
|
val[5], val[6])
|
1129
1139
|
|
1130
1140
|
@lexer.pop_cmdarg
|
1141
|
+
@lexer.pop_cond
|
1131
1142
|
@static_env.unextend
|
1132
1143
|
@context.pop
|
1133
1144
|
}
|
@@ -1152,6 +1163,7 @@ rule
|
|
1152
1163
|
{
|
1153
1164
|
@static_env.extend_static
|
1154
1165
|
@lexer.push_cmdarg
|
1166
|
+
@lexer.push_cond
|
1155
1167
|
@context.push(:def)
|
1156
1168
|
}
|
1157
1169
|
f_arglist bodystmt kEND
|
@@ -1160,6 +1172,7 @@ rule
|
|
1160
1172
|
val[3], val[4], val[5])
|
1161
1173
|
|
1162
1174
|
@lexer.pop_cmdarg
|
1175
|
+
@lexer.pop_cond
|
1163
1176
|
@static_env.unextend
|
1164
1177
|
@context.pop
|
1165
1178
|
}
|
@@ -1171,6 +1184,7 @@ rule
|
|
1171
1184
|
{
|
1172
1185
|
@static_env.extend_static
|
1173
1186
|
@lexer.push_cmdarg
|
1187
|
+
@lexer.push_cond
|
1174
1188
|
@context.push(:defs)
|
1175
1189
|
}
|
1176
1190
|
f_arglist bodystmt kEND
|
@@ -1179,6 +1193,7 @@ rule
|
|
1179
1193
|
val[4], val[6], val[7], val[8])
|
1180
1194
|
|
1181
1195
|
@lexer.pop_cmdarg
|
1196
|
+
@lexer.pop_cond
|
1182
1197
|
@static_env.unextend
|
1183
1198
|
@context.pop
|
1184
1199
|
}
|
@@ -1497,7 +1512,7 @@ opt_block_args_tail:
|
|
1497
1512
|
{
|
1498
1513
|
@context.push(:lambda)
|
1499
1514
|
}
|
1500
|
-
|
1515
|
+
bodystmt kEND
|
1501
1516
|
{
|
1502
1517
|
result = [ val[0], val[2], val[3] ]
|
1503
1518
|
@context.pop
|
@@ -1839,7 +1854,7 @@ regexp_contents: # nothing
|
|
1839
1854
|
}
|
1840
1855
|
compstmt tSTRING_DEND
|
1841
1856
|
{
|
1842
|
-
@lexer.cond.
|
1857
|
+
@lexer.cond.pop
|
1843
1858
|
@lexer.cmdarg.pop
|
1844
1859
|
|
1845
1860
|
result = @builder.begin(val[0], val[2], val[3])
|
data/lib/parser/source/buffer.rb
CHANGED
@@ -29,7 +29,7 @@ module Parser
|
|
29
29
|
# @api private
|
30
30
|
#
|
31
31
|
ENCODING_RE =
|
32
|
-
|
32
|
+
/[\s#](en)?coding\s*[:=]\s*
|
33
33
|
(
|
34
34
|
# Special-case: there's a UTF8-MAC encoding.
|
35
35
|
(utf8-mac)
|
@@ -63,6 +63,8 @@ module Parser
|
|
63
63
|
encoding_line = first_line
|
64
64
|
end
|
65
65
|
|
66
|
+
return nil if encoding_line[0] != '#'
|
67
|
+
|
66
68
|
if (result = ENCODING_RE.match(encoding_line))
|
67
69
|
Encoding.find(result[3] || result[4] || result[6])
|
68
70
|
else
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Parser
|
4
|
+
module Source
|
5
|
+
|
6
|
+
class Map::Index < Map
|
7
|
+
attr_reader :begin
|
8
|
+
attr_reader :end
|
9
|
+
attr_reader :operator
|
10
|
+
|
11
|
+
def initialize(begin_l, end_l, expression_l)
|
12
|
+
@begin, @end = begin_l, end_l
|
13
|
+
@operator = nil
|
14
|
+
|
15
|
+
super(expression_l)
|
16
|
+
end
|
17
|
+
|
18
|
+
##
|
19
|
+
# @api private
|
20
|
+
#
|
21
|
+
def with_operator(operator_l)
|
22
|
+
with { |map| map.update_operator(operator_l) }
|
23
|
+
end
|
24
|
+
|
25
|
+
protected
|
26
|
+
|
27
|
+
def update_operator(operator_l)
|
28
|
+
@operator = operator_l
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
data/lib/parser/version.rb
CHANGED
data/test/test_encoding.rb
CHANGED
@@ -87,4 +87,12 @@ class TestEncoding < Minitest::Test
|
|
87
87
|
assert_equal Encoding::KOI8_R, recognize('#encoding:koi8-r')
|
88
88
|
assert_equal Encoding::KOI8_R, recognize('#coding:koi8-r')
|
89
89
|
end
|
90
|
+
|
91
|
+
def test_underscore_and_star_characters
|
92
|
+
assert_equal Encoding::KOI8_R, recognize('# -*- encoding: koi8-r -*-')
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_garbage_around_encoding_comment
|
96
|
+
assert_equal Encoding::KOI8_R, recognize('# 1$# -*- &)* encoding: koi8-r 1$# -*- &)*')
|
97
|
+
end
|
90
98
|
end
|
data/test/test_parser.rb
CHANGED
@@ -924,11 +924,22 @@ class TestParser < Minitest::Test
|
|
924
924
|
end
|
925
925
|
|
926
926
|
def test___ENCODING__
|
927
|
+
assert_parses(
|
928
|
+
s(:__ENCODING__),
|
929
|
+
%q{__ENCODING__},
|
930
|
+
%q{~~~~~~~~~~~~ expression},
|
931
|
+
SINCE_1_9)
|
932
|
+
end
|
933
|
+
|
934
|
+
def test___ENCODING___legacy_
|
935
|
+
Parser::Builders::Default.emit_encoding = false
|
927
936
|
assert_parses(
|
928
937
|
s(:const, s(:const, nil, :Encoding), :UTF_8),
|
929
938
|
%q{__ENCODING__},
|
930
939
|
%q{~~~~~~~~~~~~ expression},
|
931
940
|
SINCE_1_9)
|
941
|
+
ensure
|
942
|
+
Parser::Builders::Default.emit_encoding = true
|
932
943
|
end
|
933
944
|
|
934
945
|
# defined?
|
@@ -1270,13 +1281,14 @@ class TestParser < Minitest::Test
|
|
1270
1281
|
s(:masgn,
|
1271
1282
|
s(:mlhs,
|
1272
1283
|
s(:send, s(:self), :a=),
|
1273
|
-
s(:
|
1284
|
+
s(:indexasgn, s(:self), s(:int, 1), s(:int, 2))),
|
1274
1285
|
s(:lvar, :foo)),
|
1275
1286
|
%q{self.a, self[1, 2] = foo},
|
1276
|
-
%q{~~~~~~ expression (mlhs.send
|
1277
|
-
| ~ selector (mlhs.send
|
1278
|
-
|
|
1279
|
-
|
|
1287
|
+
%q{~~~~~~ expression (mlhs.send)
|
1288
|
+
| ~ selector (mlhs.send)
|
1289
|
+
| ^ begin (mlhs.indexasgn)
|
1290
|
+
| ^ end (mlhs.indexasgn)
|
1291
|
+
| ~~~~~~~~~~ expression (mlhs.indexasgn)})
|
1280
1292
|
|
1281
1293
|
assert_parses(
|
1282
1294
|
s(:masgn,
|
@@ -1541,20 +1553,21 @@ class TestParser < Minitest::Test
|
|
1541
1553
|
def test_op_asgn_index
|
1542
1554
|
assert_parses(
|
1543
1555
|
s(:op_asgn,
|
1544
|
-
s(:
|
1556
|
+
s(:indexasgn, s(:lvar, :foo),
|
1545
1557
|
s(:int, 0), s(:int, 1)), :+,
|
1546
1558
|
s(:int, 2)),
|
1547
1559
|
%q{foo[0, 1] += 2},
|
1548
1560
|
%q{ ^^ operator
|
1549
|
-
|
|
1550
|
-
|
1561
|
+
| ^ begin (indexasgn)
|
1562
|
+
| ^ end (indexasgn)
|
1563
|
+
|~~~~~~~~~ expression (indexasgn)
|
1551
1564
|
|~~~~~~~~~~~~~~ expression})
|
1552
1565
|
end
|
1553
1566
|
|
1554
1567
|
def test_op_asgn_index_cmd
|
1555
1568
|
assert_parses(
|
1556
1569
|
s(:op_asgn,
|
1557
|
-
s(:
|
1570
|
+
s(:indexasgn, s(:lvar, :foo),
|
1558
1571
|
s(:int, 0), s(:int, 1)), :+,
|
1559
1572
|
s(:send, nil, :m, s(:lvar, :foo))),
|
1560
1573
|
%q{foo[0, 1] += m foo})
|
@@ -1610,13 +1623,14 @@ class TestParser < Minitest::Test
|
|
1610
1623
|
|
1611
1624
|
assert_parses(
|
1612
1625
|
s(:or_asgn,
|
1613
|
-
s(:
|
1626
|
+
s(:indexasgn, s(:lvar, :foo),
|
1614
1627
|
s(:int, 0), s(:int, 1)),
|
1615
1628
|
s(:int, 2)),
|
1616
1629
|
%q{foo[0, 1] ||= 2},
|
1617
1630
|
%q{ ^^^ operator
|
1618
|
-
|
|
1619
|
-
|
1631
|
+
| ^ begin (indexasgn)
|
1632
|
+
| ^ end (indexasgn)
|
1633
|
+
|~~~~~~~~~ expression (indexasgn)
|
1620
1634
|
|~~~~~~~~~~~~~~~ expression})
|
1621
1635
|
end
|
1622
1636
|
|
@@ -1633,13 +1647,14 @@ class TestParser < Minitest::Test
|
|
1633
1647
|
|
1634
1648
|
assert_parses(
|
1635
1649
|
s(:and_asgn,
|
1636
|
-
s(:
|
1650
|
+
s(:indexasgn, s(:lvar, :foo),
|
1637
1651
|
s(:int, 0), s(:int, 1)),
|
1638
1652
|
s(:int, 2)),
|
1639
1653
|
%q{foo[0, 1] &&= 2},
|
1640
1654
|
%q{ ^^^ operator
|
1641
|
-
|
|
1642
|
-
|
1655
|
+
| ^ begin (indexasgn)
|
1656
|
+
| ^ end (indexasgn)
|
1657
|
+
|~~~~~~~~~ expression (indexasgn)
|
1643
1658
|
|~~~~~~~~~~~~~~~ expression})
|
1644
1659
|
end
|
1645
1660
|
|
@@ -2617,6 +2632,7 @@ class TestParser < Minitest::Test
|
|
2617
2632
|
s(:arg, :a)),
|
2618
2633
|
%q{|a|}
|
2619
2634
|
)
|
2635
|
+
ensure
|
2620
2636
|
Parser::Builders::Default.emit_procarg0 = true
|
2621
2637
|
end
|
2622
2638
|
|
@@ -3346,22 +3362,47 @@ class TestParser < Minitest::Test
|
|
3346
3362
|
end
|
3347
3363
|
|
3348
3364
|
def test_send_index
|
3365
|
+
assert_parses(
|
3366
|
+
s(:index, s(:lvar, :foo),
|
3367
|
+
s(:int, 1), s(:int, 2)),
|
3368
|
+
%q{foo[1, 2]},
|
3369
|
+
%q{ ^ begin
|
3370
|
+
| ^ end
|
3371
|
+
|~~~~~~~~~ expression})
|
3372
|
+
end
|
3373
|
+
|
3374
|
+
def test_send_index_legacy
|
3375
|
+
Parser::Builders::Default.emit_index = false
|
3349
3376
|
assert_parses(
|
3350
3377
|
s(:send, s(:lvar, :foo), :[],
|
3351
3378
|
s(:int, 1), s(:int, 2)),
|
3352
3379
|
%q{foo[1, 2]},
|
3353
3380
|
%q{ ~~~~~~ selector
|
3354
3381
|
|~~~~~~~~~ expression})
|
3382
|
+
ensure
|
3383
|
+
Parser::Builders::Default.emit_index = true
|
3355
3384
|
end
|
3356
3385
|
|
3357
3386
|
def test_send_index_cmd
|
3358
3387
|
assert_parses(
|
3359
|
-
s(:
|
3388
|
+
s(:index, s(:lvar, :foo),
|
3360
3389
|
s(:send, nil, :m, s(:lvar, :bar))),
|
3361
3390
|
%q{foo[m bar]})
|
3362
3391
|
end
|
3363
3392
|
|
3364
3393
|
def test_send_index_asgn
|
3394
|
+
assert_parses(
|
3395
|
+
s(:indexasgn, s(:lvar, :foo),
|
3396
|
+
s(:int, 1), s(:int, 2), s(:int, 3)),
|
3397
|
+
%q{foo[1, 2] = 3},
|
3398
|
+
%q{ ^ begin
|
3399
|
+
| ^ end
|
3400
|
+
| ^ operator
|
3401
|
+
|~~~~~~~~~~~~~ expression})
|
3402
|
+
end
|
3403
|
+
|
3404
|
+
def test_send_index_asgn_legacy
|
3405
|
+
Parser::Builders::Default.emit_index = false
|
3365
3406
|
assert_parses(
|
3366
3407
|
s(:send, s(:lvar, :foo), :[]=,
|
3367
3408
|
s(:int, 1), s(:int, 2), s(:int, 3)),
|
@@ -3369,6 +3410,8 @@ class TestParser < Minitest::Test
|
|
3369
3410
|
%q{ ~~~~~~ selector
|
3370
3411
|
| ^ operator
|
3371
3412
|
|~~~~~~~~~~~~~ expression})
|
3413
|
+
ensure
|
3414
|
+
Parser::Builders::Default.emit_index = true
|
3372
3415
|
end
|
3373
3416
|
|
3374
3417
|
def test_send_lambda
|
@@ -3473,6 +3516,7 @@ class TestParser < Minitest::Test
|
|
3473
3516
|
| ^ end
|
3474
3517
|
|~~~~~ expression},
|
3475
3518
|
SINCE_1_9)
|
3519
|
+
ensure
|
3476
3520
|
Parser::Builders::Default.emit_lambda = true
|
3477
3521
|
end
|
3478
3522
|
|
@@ -3698,7 +3742,7 @@ class TestParser < Minitest::Test
|
|
3698
3742
|
|
3699
3743
|
def test_args_args_comma
|
3700
3744
|
assert_parses(
|
3701
|
-
s(:
|
3745
|
+
s(:index, s(:lvar, :foo),
|
3702
3746
|
s(:lvar, :bar)),
|
3703
3747
|
%q{foo[bar,]},
|
3704
3748
|
%q{},
|
@@ -3739,7 +3783,7 @@ class TestParser < Minitest::Test
|
|
3739
3783
|
|
3740
3784
|
def test_args_assocs_comma
|
3741
3785
|
assert_parses(
|
3742
|
-
s(:
|
3786
|
+
s(:index, s(:lvar, :foo),
|
3743
3787
|
s(:hash, s(:pair, s(:sym, :baz), s(:int, 1)))),
|
3744
3788
|
%q{foo[:baz => 1,]},
|
3745
3789
|
%q{},
|
@@ -3763,7 +3807,7 @@ class TestParser < Minitest::Test
|
|
3763
3807
|
|
3764
3808
|
def test_args_args_assocs_comma
|
3765
3809
|
assert_parses(
|
3766
|
-
s(:
|
3810
|
+
s(:index, s(:lvar, :foo),
|
3767
3811
|
s(:lvar, :bar),
|
3768
3812
|
s(:hash, s(:pair, s(:sym, :baz), s(:int, 1)))),
|
3769
3813
|
%q{foo[bar, :baz => 1,]},
|
@@ -5776,8 +5820,8 @@ class TestParser < Minitest::Test
|
|
5776
5820
|
|
5777
5821
|
assert_parses(
|
5778
5822
|
s(:op_asgn,
|
5779
|
-
s(:
|
5780
|
-
s(:lvar, :foo),
|
5823
|
+
s(:indexasgn,
|
5824
|
+
s(:lvar, :foo),
|
5781
5825
|
s(:int, 0)), :+,
|
5782
5826
|
s(:rescue,
|
5783
5827
|
s(:send, nil, :raise,
|
@@ -5865,8 +5909,8 @@ class TestParser < Minitest::Test
|
|
5865
5909
|
|
5866
5910
|
assert_parses(
|
5867
5911
|
s(:op_asgn,
|
5868
|
-
s(:
|
5869
|
-
s(:lvar, :foo),
|
5912
|
+
s(:indexasgn,
|
5913
|
+
s(:lvar, :foo),
|
5870
5914
|
s(:int, 0)), :+,
|
5871
5915
|
s(:rescue,
|
5872
5916
|
s(:send, nil, :raise,
|
@@ -6484,6 +6528,136 @@ class TestParser < Minitest::Test
|
|
6484
6528
|
end
|
6485
6529
|
end
|
6486
6530
|
|
6531
|
+
def test_method_definition_in_while_cond
|
6532
|
+
assert_parses(
|
6533
|
+
s(:while,
|
6534
|
+
s(:def, :foo,
|
6535
|
+
s(:args),
|
6536
|
+
s(:block,
|
6537
|
+
s(:send, nil, :tap),
|
6538
|
+
s(:args), nil)),
|
6539
|
+
s(:break)),
|
6540
|
+
%q{while def foo; tap do end; end; break; end},
|
6541
|
+
%q{},
|
6542
|
+
SINCE_2_5)
|
6543
|
+
|
6544
|
+
assert_parses(
|
6545
|
+
s(:while,
|
6546
|
+
s(:defs,
|
6547
|
+
s(:self), :foo,
|
6548
|
+
s(:args),
|
6549
|
+
s(:block,
|
6550
|
+
s(:send, nil, :tap),
|
6551
|
+
s(:args), nil)),
|
6552
|
+
s(:break)),
|
6553
|
+
%q{while def self.foo; tap do end; end; break; end},
|
6554
|
+
%q{},
|
6555
|
+
SINCE_2_5)
|
6556
|
+
|
6557
|
+
assert_parses(
|
6558
|
+
s(:while,
|
6559
|
+
s(:def, :foo,
|
6560
|
+
s(:args,
|
6561
|
+
s(:optarg, :a,
|
6562
|
+
s(:block,
|
6563
|
+
s(:send, nil, :tap),
|
6564
|
+
s(:args), nil))), nil),
|
6565
|
+
s(:break)),
|
6566
|
+
%q{while def foo a = tap do end; end; break; end},
|
6567
|
+
%q{},
|
6568
|
+
SINCE_2_5)
|
6569
|
+
|
6570
|
+
assert_parses(
|
6571
|
+
s(:while,
|
6572
|
+
s(:defs,
|
6573
|
+
s(:self), :foo,
|
6574
|
+
s(:args,
|
6575
|
+
s(:optarg, :a,
|
6576
|
+
s(:block,
|
6577
|
+
s(:send, nil, :tap),
|
6578
|
+
s(:args), nil))), nil),
|
6579
|
+
s(:break)),
|
6580
|
+
%q{while def self.foo a = tap do end; end; break; end},
|
6581
|
+
%q{},
|
6582
|
+
SINCE_2_5)
|
6583
|
+
end
|
6584
|
+
|
6585
|
+
def test_class_definition_in_while_cond
|
6586
|
+
assert_parses(
|
6587
|
+
s(:while,
|
6588
|
+
s(:class,
|
6589
|
+
s(:const, nil, :Foo), nil,
|
6590
|
+
s(:block,
|
6591
|
+
s(:send, nil, :tap),
|
6592
|
+
s(:args), nil)),
|
6593
|
+
s(:break)),
|
6594
|
+
%q{while class Foo; tap do end; end; break; end},
|
6595
|
+
%q{},
|
6596
|
+
SINCE_2_5)
|
6597
|
+
|
6598
|
+
assert_parses(
|
6599
|
+
s(:while,
|
6600
|
+
s(:class,
|
6601
|
+
s(:const, nil, :Foo), nil,
|
6602
|
+
s(:lvasgn, :a,
|
6603
|
+
s(:block,
|
6604
|
+
s(:send, nil, :tap),
|
6605
|
+
s(:args), nil))),
|
6606
|
+
s(:break)),
|
6607
|
+
%q{while class Foo a = tap do end; end; break; end},
|
6608
|
+
%q{},
|
6609
|
+
SINCE_2_5)
|
6610
|
+
|
6611
|
+
assert_parses(
|
6612
|
+
s(:while,
|
6613
|
+
s(:sclass,
|
6614
|
+
s(:self),
|
6615
|
+
s(:block,
|
6616
|
+
s(:send, nil, :tap),
|
6617
|
+
s(:args), nil)),
|
6618
|
+
s(:break)),
|
6619
|
+
%q{while class << self; tap do end; end; break; end},
|
6620
|
+
%q{},
|
6621
|
+
SINCE_2_5)
|
6622
|
+
|
6623
|
+
assert_parses(
|
6624
|
+
s(:while,
|
6625
|
+
s(:sclass,
|
6626
|
+
s(:self),
|
6627
|
+
s(:lvasgn, :a,
|
6628
|
+
s(:block,
|
6629
|
+
s(:send, nil, :tap),
|
6630
|
+
s(:args), nil))),
|
6631
|
+
s(:break)),
|
6632
|
+
%q{while class << self; a = tap do end; end; break; end},
|
6633
|
+
%q{},
|
6634
|
+
SINCE_2_5)
|
6635
|
+
end
|
6636
|
+
|
6637
|
+
def test_rescue_in_lambda_block
|
6638
|
+
assert_diagnoses(
|
6639
|
+
[:error, :unexpected_token, { :token => 'kRESCUE'}],
|
6640
|
+
%q{-> do rescue; end},
|
6641
|
+
%q{ ~~~~~~ location},
|
6642
|
+
SINCE_1_9 - SINCE_2_5)
|
6643
|
+
|
6644
|
+
assert_parses(
|
6645
|
+
s(:block,
|
6646
|
+
s(:lambda),
|
6647
|
+
s(:args),
|
6648
|
+
s(:rescue, nil,
|
6649
|
+
s(:resbody, nil, nil, nil), nil)),
|
6650
|
+
%q{-> do rescue; end},
|
6651
|
+
%q{ ~~~~~~ keyword (rescue.resbody)},
|
6652
|
+
SINCE_2_5)
|
6653
|
+
|
6654
|
+
assert_diagnoses(
|
6655
|
+
[:error, :unexpected_token, { :token => 'kRESCUE'}],
|
6656
|
+
%q{-> { rescue; }},
|
6657
|
+
%q{ ~~~~~~ location},
|
6658
|
+
SINCE_1_9)
|
6659
|
+
end
|
6660
|
+
|
6487
6661
|
def test_ruby_bug_13547
|
6488
6662
|
assert_diagnoses(
|
6489
6663
|
[:error, :unexpected_token, { :token => 'tLCURLY' }],
|
@@ -6559,8 +6733,8 @@ class TestParser < Minitest::Test
|
|
6559
6733
|
|
6560
6734
|
assert_parses(
|
6561
6735
|
s(:block,
|
6562
|
-
s(:
|
6563
|
-
s(:send, nil, :meth)
|
6736
|
+
s(:index,
|
6737
|
+
s(:send, nil, :meth)),
|
6564
6738
|
s(:args), nil),
|
6565
6739
|
%q{meth[] {}},
|
6566
6740
|
%q{},
|
@@ -6583,4 +6757,28 @@ class TestParser < Minitest::Test
|
|
6583
6757
|
%q{m /foo/x {}},
|
6584
6758
|
SINCE_2_4)
|
6585
6759
|
end
|
6760
|
+
|
6761
|
+
def test_bug_447
|
6762
|
+
assert_parses(
|
6763
|
+
s(:block,
|
6764
|
+
s(:send, nil, :m,
|
6765
|
+
s(:array)),
|
6766
|
+
s(:args), nil),
|
6767
|
+
%q{m [] do end},
|
6768
|
+
%q{},
|
6769
|
+
ALL_VERSIONS)
|
6770
|
+
end
|
6771
|
+
|
6772
|
+
def test_bug_435
|
6773
|
+
assert_parses(
|
6774
|
+
s(:dstr,
|
6775
|
+
s(:begin,
|
6776
|
+
s(:block,
|
6777
|
+
s(:lambda),
|
6778
|
+
s(:args,
|
6779
|
+
s(:arg, :foo)), nil))),
|
6780
|
+
%q{"#{-> foo {}}"},
|
6781
|
+
%q{},
|
6782
|
+
SINCE_1_9)
|
6783
|
+
end
|
6586
6784
|
end
|
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.5.0.
|
4
|
+
version: 2.5.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- whitequark
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-02-
|
11
|
+
date: 2018-02-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ast
|
@@ -230,6 +230,7 @@ files:
|
|
230
230
|
- lib/parser/source/map/definition.rb
|
231
231
|
- lib/parser/source/map/for.rb
|
232
232
|
- lib/parser/source/map/heredoc.rb
|
233
|
+
- lib/parser/source/map/index.rb
|
233
234
|
- lib/parser/source/map/keyword.rb
|
234
235
|
- lib/parser/source/map/objc_kwarg.rb
|
235
236
|
- lib/parser/source/map/operator.rb
|