parser 2.5.0.0 → 2.5.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|