parser 2.2.0.pre.4 → 2.2.0.pre.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -0
- data/CHANGELOG.md +11 -0
- data/README.md +9 -2
- data/lib/parser/builders/default.rb +28 -2
- data/lib/parser/current.rb +4 -0
- data/lib/parser/lexer.rl +56 -14
- data/lib/parser/lexer/explanation.rb +3 -1
- data/lib/parser/lexer/literal.rb +5 -2
- data/lib/parser/messages.rb +1 -1
- data/lib/parser/ruby21.y +8 -2
- data/lib/parser/ruby22.y +23 -5
- data/lib/parser/runner/ruby_rewrite.rb +3 -2
- data/lib/parser/version.rb +1 -1
- data/parser.gemspec +1 -1
- data/test/bug_163/fixtures/input.rb +3 -0
- data/test/bug_163/fixtures/output.rb +3 -0
- data/test/bug_163/rewriter.rb +18 -0
- data/test/bug_163/test_runner_rewrite.rb +35 -0
- data/test/helper.rb +1 -0
- data/test/test_lexer.rb +20 -0
- data/test/test_parser.rb +52 -2
- metadata +14 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 977914667b7d556b1153734867b2fb49d8159bd3
|
4
|
+
data.tar.gz: f4ed048c2734f36642ae38f7ab2f6560f75a53e4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7a754063cb5fd5ab4b5598c2cdbc93b8b0dabb2722141f4eb02e3045c41d454ff8f6c384ced09cefebfb8243b35967b2e4d7429da513e32e5d1d18ab1a3e201b
|
7
|
+
data.tar.gz: ba4530392c1b0ccfa7af114c2c8c1f17983b1824251441b6666fc137df9e1f52e0108088a3f63517339d7bf5f06e2d1c2a466620ebde6099a7e29f334a8242ea
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,17 @@
|
|
1
1
|
Changelog
|
2
2
|
=========
|
3
3
|
|
4
|
+
v2.2.0.pre.5 (2014-10-03)
|
5
|
+
-------------------------
|
6
|
+
|
7
|
+
Features implemented:
|
8
|
+
* parser/current: add syntax deviation warning for 2.1.2. (Peter Zotov)
|
9
|
+
* lexer.rl, ruby22.y: "{'x':1}": add tLABEL_END. (Peter Zotov)
|
10
|
+
|
11
|
+
Bugs fixed:
|
12
|
+
* lexer.rl, ruby{21,22}.y: "def a b:\nreturn": fix #164. (Peter Zotov)
|
13
|
+
* Fix for `ruby-rewrite` not rewriting files if any rewriter was loaded, due to it getting confused about the filename. (Jon Frisby)
|
14
|
+
|
4
15
|
v2.2.0.pre.4 (2014-08-09)
|
5
16
|
-------------------------
|
6
17
|
|
data/README.md
CHANGED
@@ -118,8 +118,7 @@ with Parser:
|
|
118
118
|
|
119
119
|
## Documentation
|
120
120
|
|
121
|
-
Documentation for parser is available online
|
122
|
-
[rdoc.info](http://rdoc.info/github/whitequark/parser).
|
121
|
+
Documentation for parser is available [online](http://whitequark.github.io/parser/).
|
123
122
|
|
124
123
|
### Node names
|
125
124
|
|
@@ -197,6 +196,14 @@ $ ruby-parse -e '(foo) while cond'
|
|
197
196
|
|
198
197
|
(Parser also needs the `(kwbegin)` node type internally, and it is highly problematic to map it back to `(begin)`.)
|
199
198
|
|
199
|
+
## Compatibility with Ruby MRI
|
200
|
+
|
201
|
+
Unfortunately, Ruby MRI often changes syntax in patchlevel versions. This has happened, at least, for every release since 1.9; for example, commits [c5013452](https://github.com/ruby/ruby/commit/c501345218dc5fb0fae90d56a0c6fd19d38df5bb) and [04bb9d6b](https://github.com/ruby/ruby/commit/04bb9d6b75a55d4000700769eead5a5cb942c25b) were backported all the way from HEAD to 1.9. Moreover, there is no simple way to track these changes.
|
202
|
+
|
203
|
+
This policy makes it all but impossible to make Parser precisely compatible with the Ruby MRI parser. Indeed, at September 2014, it would be necessary to maintain and update ten different parsers together with their lexer quirks in order to be able to emulate any given released Ruby MRI version.
|
204
|
+
|
205
|
+
As a result, Parser chooses a different path: the `parser/rubyXY` parsers recognize the syntax of the latest minor version of Ruby MRI X.Y at the time of the gem release.
|
206
|
+
|
200
207
|
## Known issues
|
201
208
|
|
202
209
|
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.
|
@@ -251,6 +251,14 @@ module Parser
|
|
251
251
|
n(:pair, [ key, value ], pair_map)
|
252
252
|
end
|
253
253
|
|
254
|
+
def pair_quoted(begin_t, parts, end_t, value)
|
255
|
+
end_t, pair_map = pair_quoted_map(begin_t, end_t, value)
|
256
|
+
|
257
|
+
key = symbol_compose(begin_t, parts, end_t)
|
258
|
+
|
259
|
+
n(:pair, [ key, value ], pair_map)
|
260
|
+
end
|
261
|
+
|
254
262
|
def kwsplat(dstar_t, arg)
|
255
263
|
n(:kwsplat, [ arg ],
|
256
264
|
unary_op_map(dstar_t, arg))
|
@@ -1091,14 +1099,32 @@ module Parser
|
|
1091
1099
|
key_range.end_pos - 1,
|
1092
1100
|
key_range.end_pos)
|
1093
1101
|
|
1094
|
-
|
1095
|
-
|
1102
|
+
[ # key map
|
1103
|
+
Source::Map::Collection.new(nil, nil,
|
1096
1104
|
key_l),
|
1097
1105
|
# pair map
|
1098
1106
|
Source::Map::Operator.new(colon_l,
|
1099
1107
|
key_range.join(value_e.loc.expression)) ]
|
1100
1108
|
end
|
1101
1109
|
|
1110
|
+
def pair_quoted_map(begin_t, end_t, value_e)
|
1111
|
+
end_l = loc(end_t)
|
1112
|
+
|
1113
|
+
quote_l = Source::Range.new(end_l.source_buffer,
|
1114
|
+
end_l.end_pos - 2,
|
1115
|
+
end_l.end_pos - 1)
|
1116
|
+
|
1117
|
+
colon_l = Source::Range.new(end_l.source_buffer,
|
1118
|
+
end_l.end_pos - 1,
|
1119
|
+
end_l.end_pos)
|
1120
|
+
|
1121
|
+
[ # modified end token
|
1122
|
+
[ value(end_t), quote_l ],
|
1123
|
+
# pair map
|
1124
|
+
Source::Map::Operator.new(colon_l,
|
1125
|
+
loc(begin_t).join(value_e.loc.expression)) ]
|
1126
|
+
end
|
1127
|
+
|
1102
1128
|
def expr_map(loc)
|
1103
1129
|
Source::Map.new(loc)
|
1104
1130
|
end
|
data/lib/parser/current.rb
CHANGED
data/lib/parser/lexer.rl
CHANGED
@@ -94,7 +94,7 @@ class Parser::Lexer
|
|
94
94
|
attr_accessor :static_env
|
95
95
|
attr_accessor :force_utf32
|
96
96
|
|
97
|
-
attr_accessor :cond, :cmdarg
|
97
|
+
attr_accessor :cond, :cmdarg, :in_kwarg
|
98
98
|
|
99
99
|
attr_accessor :tokens, :comments
|
100
100
|
|
@@ -116,6 +116,7 @@ class Parser::Lexer
|
|
116
116
|
|
117
117
|
@cond = StackState.new('cond')
|
118
118
|
@cmdarg = StackState.new('cmdarg')
|
119
|
+
@cond_stack = []
|
119
120
|
@cmdarg_stack = []
|
120
121
|
end
|
121
122
|
|
@@ -163,6 +164,9 @@ class Parser::Lexer
|
|
163
164
|
# at the entry to #advance, it will transition to expr_cmdarg
|
164
165
|
# instead of expr_arg at certain points.
|
165
166
|
@command_state = false
|
167
|
+
|
168
|
+
# True at the end of "def foo a:"
|
169
|
+
@in_kwarg = false
|
166
170
|
end
|
167
171
|
|
168
172
|
def source_buffer=(source_buffer)
|
@@ -214,17 +218,18 @@ class Parser::Lexer
|
|
214
218
|
end
|
215
219
|
|
216
220
|
LEX_STATES = {
|
217
|
-
:line_begin
|
218
|
-
:expr_dot
|
219
|
-
:expr_fname
|
220
|
-
:expr_value
|
221
|
-
:expr_beg
|
222
|
-
:expr_mid
|
223
|
-
:expr_arg
|
224
|
-
:expr_cmdarg
|
225
|
-
:expr_end
|
226
|
-
:expr_endarg
|
227
|
-
:expr_endfn
|
221
|
+
:line_begin => lex_en_line_begin,
|
222
|
+
:expr_dot => lex_en_expr_dot,
|
223
|
+
:expr_fname => lex_en_expr_fname,
|
224
|
+
:expr_value => lex_en_expr_value,
|
225
|
+
:expr_beg => lex_en_expr_beg,
|
226
|
+
:expr_mid => lex_en_expr_mid,
|
227
|
+
:expr_arg => lex_en_expr_arg,
|
228
|
+
:expr_cmdarg => lex_en_expr_cmdarg,
|
229
|
+
:expr_end => lex_en_expr_end,
|
230
|
+
:expr_endarg => lex_en_expr_endarg,
|
231
|
+
:expr_endfn => lex_en_expr_endfn,
|
232
|
+
:expr_labelarg => lex_en_expr_labelarg,
|
228
233
|
|
229
234
|
:interp_string => lex_en_interp_string,
|
230
235
|
:interp_words => lex_en_interp_words,
|
@@ -249,6 +254,15 @@ class Parser::Lexer
|
|
249
254
|
@cmdarg = @cmdarg_stack.pop
|
250
255
|
end
|
251
256
|
|
257
|
+
def push_cond
|
258
|
+
@cond_stack.push(@cond)
|
259
|
+
@cond = StackState.new("cond.#{@cond_stack.count}")
|
260
|
+
end
|
261
|
+
|
262
|
+
def pop_cond
|
263
|
+
@cond = @cond_stack.pop
|
264
|
+
end
|
265
|
+
|
252
266
|
# Return next token: [type, value].
|
253
267
|
def advance
|
254
268
|
if @token_queue.any?
|
@@ -816,7 +830,14 @@ class Parser::Lexer
|
|
816
830
|
string = @source[@ts...@te]
|
817
831
|
string = string.encode(@encoding) if string.respond_to?(:encode)
|
818
832
|
|
819
|
-
|
833
|
+
# tLABEL_END is only possible in non-cond context on >= 2.2
|
834
|
+
if @version >= 22 && !@cond.active?
|
835
|
+
lookahead = @source[@te...@te+1]
|
836
|
+
lookahead = lookahead.encode(@encoding) if lookahead.respond_to?(:encode)
|
837
|
+
end
|
838
|
+
|
839
|
+
if !literal.heredoc? && (token = literal.nest_and_try_closing(string, @ts, @te, lookahead))
|
840
|
+
p += 1 if token[0] == :tLABEL_END
|
820
841
|
fnext *pop_literal; fbreak;
|
821
842
|
else
|
822
843
|
literal.extend_string(string, @ts, @te)
|
@@ -1276,7 +1297,7 @@ class Parser::Lexer
|
|
1276
1297
|
expr_endfn := |*
|
1277
1298
|
label
|
1278
1299
|
=> { emit(:tLABEL, tok(@ts, @te - 1))
|
1279
|
-
fnext
|
1300
|
+
fnext expr_labelarg; fbreak; };
|
1280
1301
|
|
1281
1302
|
w_space_comment;
|
1282
1303
|
|
@@ -1753,6 +1774,7 @@ class Parser::Lexer
|
|
1753
1774
|
end
|
1754
1775
|
else
|
1755
1776
|
emit(:tLABEL, tok(@ts, @te - 2), @ts, @te - 1)
|
1777
|
+
fnext expr_labelarg;
|
1756
1778
|
end
|
1757
1779
|
|
1758
1780
|
fbreak;
|
@@ -1799,6 +1821,26 @@ class Parser::Lexer
|
|
1799
1821
|
c_eof => do_eof;
|
1800
1822
|
*|;
|
1801
1823
|
|
1824
|
+
# Special newline handling for "def a b:"
|
1825
|
+
#
|
1826
|
+
expr_labelarg := |*
|
1827
|
+
w_space_comment;
|
1828
|
+
|
1829
|
+
w_newline
|
1830
|
+
=> {
|
1831
|
+
if @in_kwarg
|
1832
|
+
fhold; fgoto expr_end;
|
1833
|
+
else
|
1834
|
+
fgoto line_begin;
|
1835
|
+
end
|
1836
|
+
};
|
1837
|
+
|
1838
|
+
c_any
|
1839
|
+
=> { fhold; fgoto expr_beg; };
|
1840
|
+
|
1841
|
+
c_eof => do_eof;
|
1842
|
+
*|;
|
1843
|
+
|
1802
1844
|
# Like expr_beg, but no 1.9 label possible.
|
1803
1845
|
#
|
1804
1846
|
expr_value := |*
|
@@ -16,9 +16,11 @@ module Parser
|
|
16
16
|
def advance
|
17
17
|
type, (val, range) = advance_before_explanation
|
18
18
|
|
19
|
+
more = "(in-kwarg)" if @in_kwarg
|
20
|
+
|
19
21
|
puts decorate(range,
|
20
22
|
"\e[0;32m#{type} #{val.inspect}\e[0m",
|
21
|
-
"#{state.to_s.ljust(12)} #{@cond} #{@cmdarg}\e[0m")
|
23
|
+
"#{state.to_s.ljust(12)} #{@cond} #{@cmdarg} #{more}\e[0m")
|
22
24
|
|
23
25
|
[ type, [val, range] ]
|
24
26
|
end
|
data/lib/parser/lexer/literal.rb
CHANGED
@@ -114,7 +114,7 @@ module Parser
|
|
114
114
|
end
|
115
115
|
end
|
116
116
|
|
117
|
-
def nest_and_try_closing(delimiter, ts, te)
|
117
|
+
def nest_and_try_closing(delimiter, ts, te, lookahead=nil)
|
118
118
|
delimiter = coerce_encoding(delimiter)
|
119
119
|
|
120
120
|
if @start_delim && @start_delim == delimiter
|
@@ -130,7 +130,10 @@ module Parser
|
|
130
130
|
end
|
131
131
|
|
132
132
|
# Emit the string as a single token if it's applicable.
|
133
|
-
if @
|
133
|
+
if lookahead == ':' && %w(' ").include?(delimiter) && @start_tok == :tSTRING_BEG
|
134
|
+
flush_string
|
135
|
+
emit(:tLABEL_END, @end_delim, ts, te + 1)
|
136
|
+
elsif @monolithic
|
134
137
|
emit(MONOLITHIC[@start_tok], @buffer, @str_s, te)
|
135
138
|
else
|
136
139
|
# If this is a heredoc, @buffer contains the sentinel now.
|
data/lib/parser/messages.rb
CHANGED
@@ -29,7 +29,7 @@ module Parser
|
|
29
29
|
|
30
30
|
# Lexer warnings
|
31
31
|
:invalid_escape_use => 'invalid character syntax; use ?%{escape}',
|
32
|
-
:ambiguous_literal => 'ambiguous first argument;
|
32
|
+
:ambiguous_literal => 'ambiguous first argument; put parentheses or a space even after the operator',
|
33
33
|
:ambiguous_prefix => "`%{prefix}' interpreted as argument prefix",
|
34
34
|
|
35
35
|
# Parser errors
|
data/lib/parser/ruby21.y
CHANGED
@@ -1956,11 +1956,17 @@ keyword_variable: kNIL
|
|
1956
1956
|
|
1957
1957
|
@lexer.state = :expr_value
|
1958
1958
|
}
|
1959
|
-
|
|
1959
|
+
| {
|
1960
|
+
result = @lexer.in_kwarg
|
1961
|
+
@lexer.in_kwarg = true
|
1962
|
+
}
|
1963
|
+
f_args term
|
1960
1964
|
{
|
1961
|
-
|
1965
|
+
@lexer.in_kwarg = val[0]
|
1966
|
+
result = @builder.args(nil, val[1], nil)
|
1962
1967
|
}
|
1963
1968
|
|
1969
|
+
|
1964
1970
|
args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
|
1965
1971
|
{
|
1966
1972
|
result = val[0].concat(val[2]).concat(val[3])
|
data/lib/parser/ruby22.y
CHANGED
@@ -17,7 +17,7 @@ token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
|
|
17
17
|
tWORDS_BEG tQWORDS_BEG tSYMBOLS_BEG tQSYMBOLS_BEG tSTRING_DBEG
|
18
18
|
tSTRING_DVAR tSTRING_END tSTRING_DEND tSTRING tSYMBOL
|
19
19
|
tNL tEH tCOLON tCOMMA tSPACE tSEMI tLAMBDA tLAMBEG tCHARACTER
|
20
|
-
tRATIONAL tIMAGINARY
|
20
|
+
tRATIONAL tIMAGINARY tLABEL_END
|
21
21
|
|
22
22
|
prechigh
|
23
23
|
right tBANG tTILDE tUPLUS
|
@@ -785,10 +785,19 @@ rule
|
|
785
785
|
result = @builder.keyword_cmd(:defined?, val[0], nil, [ val[2] ], nil)
|
786
786
|
}
|
787
787
|
|
788
|
-
| arg tEH
|
788
|
+
| arg tEH
|
789
|
+
{
|
790
|
+
@lexer.push_cond
|
791
|
+
@lexer.cond.push(true)
|
792
|
+
}
|
793
|
+
arg opt_nl tCOLON
|
794
|
+
{
|
795
|
+
@lexer.pop_cond
|
796
|
+
}
|
797
|
+
arg
|
789
798
|
{
|
790
799
|
result = @builder.ternary(val[0], val[1],
|
791
|
-
val[
|
800
|
+
val[3], val[5], val[7])
|
792
801
|
}
|
793
802
|
| primary
|
794
803
|
|
@@ -1956,9 +1965,14 @@ keyword_variable: kNIL
|
|
1956
1965
|
|
1957
1966
|
@lexer.state = :expr_value
|
1958
1967
|
}
|
1959
|
-
|
|
1968
|
+
| {
|
1969
|
+
result = @lexer.in_kwarg
|
1970
|
+
@lexer.in_kwarg = true
|
1971
|
+
}
|
1972
|
+
f_args term
|
1960
1973
|
{
|
1961
|
-
|
1974
|
+
@lexer.in_kwarg = val[0]
|
1975
|
+
result = @builder.args(nil, val[1], nil)
|
1962
1976
|
}
|
1963
1977
|
|
1964
1978
|
args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
|
@@ -2271,6 +2285,10 @@ keyword_variable: kNIL
|
|
2271
2285
|
{
|
2272
2286
|
result = @builder.pair_keyword(val[0], val[1])
|
2273
2287
|
}
|
2288
|
+
| tSTRING_BEG string_contents tLABEL_END arg_value
|
2289
|
+
{
|
2290
|
+
result = @builder.pair_quoted(val[0], val[1], val[2], val[3])
|
2291
|
+
}
|
2274
2292
|
| tDSTAR arg_value
|
2275
2293
|
{
|
2276
2294
|
result = @builder.kwsplat(val[0], val[1])
|
@@ -43,6 +43,7 @@ module Parser
|
|
43
43
|
|
44
44
|
def process(initial_buffer)
|
45
45
|
buffer = initial_buffer
|
46
|
+
original_name = buffer.name
|
46
47
|
|
47
48
|
@rewriters.each do |rewriter_class|
|
48
49
|
@parser.reset
|
@@ -81,8 +82,8 @@ module Parser
|
|
81
82
|
buffer = new_buffer
|
82
83
|
end
|
83
84
|
|
84
|
-
if File.exist?(
|
85
|
-
File.open(
|
85
|
+
if File.exist?(original_name)
|
86
|
+
File.open(original_name, 'w') do |file|
|
86
87
|
file.write buffer.source
|
87
88
|
end
|
88
89
|
else
|
data/lib/parser/version.rb
CHANGED
data/parser.gemspec
CHANGED
@@ -29,7 +29,7 @@ Gem::Specification.new do |spec|
|
|
29
29
|
spec.add_dependency 'slop', ['~> 3.4', '>= 3.4.5']
|
30
30
|
|
31
31
|
spec.add_development_dependency 'bundler', '~> 1.2'
|
32
|
-
spec.add_development_dependency 'rake',
|
32
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
33
33
|
spec.add_development_dependency 'racc', '= 1.4.9' # update to 1.4.11 when it's done
|
34
34
|
spec.add_development_dependency 'cliver', '~> 0.3.0'
|
35
35
|
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class Rewriter < Parser::Rewriter
|
2
|
+
def on_if(node)
|
3
|
+
# Crude, totally-not-usable-in-the-real-world code to remove optional
|
4
|
+
# parens from control keywords.
|
5
|
+
#
|
6
|
+
# In a perfect test scenario we'd simply make this a no-op, to demonstrate
|
7
|
+
# that the bug happens when any rewriter is loaded regardless of whether it
|
8
|
+
# actually changes anything but that makes assertions much harder to get
|
9
|
+
# right. It's much easier to just show that the file did, or did not
|
10
|
+
# get changed.
|
11
|
+
if node.children[0].type == :begin
|
12
|
+
replace node.children[0].loc.begin, ' '
|
13
|
+
remove node.children[0].loc.end
|
14
|
+
end
|
15
|
+
|
16
|
+
super
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'shellwords'
|
4
|
+
|
5
|
+
BASE_DIR = Pathname.new(__FILE__) + '../..'
|
6
|
+
require (BASE_DIR + 'helper').expand_path
|
7
|
+
|
8
|
+
class TestRunnerRewrite < Minitest::Test
|
9
|
+
def setup
|
10
|
+
@ruby_rewrite = BASE_DIR.expand_path + '../bin/ruby-rewrite'
|
11
|
+
@test_dir = BASE_DIR + 'bug_163'
|
12
|
+
@fixtures_dir = @test_dir + 'fixtures'
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_rewriter
|
16
|
+
Dir.mktmpdir("parser", BASE_DIR.expand_path.to_s) do |tmp_dir|
|
17
|
+
tmp_dir = Pathname.new(tmp_dir)
|
18
|
+
sample_file = tmp_dir + 'bug_163.rb'
|
19
|
+
sample_file_expanded = sample_file.expand_path
|
20
|
+
expected_file = @fixtures_dir + 'output.rb'
|
21
|
+
|
22
|
+
FileUtils.cp(@fixtures_dir + 'input.rb', tmp_dir + 'bug_163.rb')
|
23
|
+
FileUtils.cd @test_dir do
|
24
|
+
exit_code = system %Q{
|
25
|
+
#{Shellwords.escape(@ruby_rewrite.to_s)} --modify \
|
26
|
+
-l rewriter.rb \
|
27
|
+
#{Shellwords.escape(sample_file_expanded.to_s)}
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
assert File.read(expected_file.expand_path) == File.read(sample_file),
|
32
|
+
"#{sample_file} should be identical to #{expected_file}"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/test/helper.rb
CHANGED
data/test/test_lexer.rb
CHANGED
@@ -273,6 +273,26 @@ class TestLexer < Minitest::Test
|
|
273
273
|
:kTRUE, 'true')
|
274
274
|
end
|
275
275
|
|
276
|
+
def test_label__22
|
277
|
+
setup_lexer 22
|
278
|
+
|
279
|
+
assert_scanned("{'a':",
|
280
|
+
:tLBRACE, '{',
|
281
|
+
:tSTRING_BEG, "'",
|
282
|
+
:tSTRING_CONTENT, 'a',
|
283
|
+
:tLABEL_END, "'")
|
284
|
+
end
|
285
|
+
|
286
|
+
def test_label_nested__22
|
287
|
+
setup_lexer 22
|
288
|
+
|
289
|
+
assert_scanned("{'a\":':",
|
290
|
+
:tLBRACE, '{',
|
291
|
+
:tSTRING_BEG, "'",
|
292
|
+
:tSTRING_CONTENT, 'a":',
|
293
|
+
:tLABEL_END, "'")
|
294
|
+
end
|
295
|
+
|
276
296
|
def test_command_start__19
|
277
297
|
setup_lexer 19
|
278
298
|
|
data/test/test_parser.rb
CHANGED
@@ -559,7 +559,31 @@ class TestParser < Minitest::Test
|
|
559
559
|
| ~~~ expression (pair.sym)
|
560
560
|
| ~~~~~~ expression (pair)
|
561
561
|
|~~~~~~~~~~ expression},
|
562
|
-
|
562
|
+
ALL_VERSIONS - %w(1.8))
|
563
|
+
end
|
564
|
+
|
565
|
+
def test_hash_label_end
|
566
|
+
assert_parses(
|
567
|
+
s(:hash, s(:pair, s(:sym, :foo), s(:int, 2))),
|
568
|
+
%q[{ 'foo': 2 }],
|
569
|
+
%q{^ begin
|
570
|
+
| ^ end
|
571
|
+
| ^ operator (pair)
|
572
|
+
| ^ begin (pair.sym)
|
573
|
+
| ^ end (pair.sym)
|
574
|
+
| ~~~~~ expression (pair.sym)
|
575
|
+
| ~~~~~~~~ expression (pair)
|
576
|
+
|~~~~~~~~~~~~ expression},
|
577
|
+
ALL_VERSIONS - %w(1.8 1.9 2.0 2.1))
|
578
|
+
|
579
|
+
assert_parses(
|
580
|
+
s(:send, nil, :f,
|
581
|
+
s(:if, s(:send, nil, :a),
|
582
|
+
s(:str, "a"),
|
583
|
+
s(:int, 1))),
|
584
|
+
%q{f(a ? "a":1)},
|
585
|
+
%q{},
|
586
|
+
ALL_VERSIONS - %w(1.8 1.9 2.0 2.1))
|
563
587
|
end
|
564
588
|
|
565
589
|
def test_hash_kwsplat
|
@@ -570,7 +594,7 @@ class TestParser < Minitest::Test
|
|
570
594
|
%q[{ foo: 2, **bar }],
|
571
595
|
%q{ ^^ operator (kwsplat)
|
572
596
|
| ~~~~~ expression (kwsplat)},
|
573
|
-
|
597
|
+
ALL_VERSIONS - %w(1.8 1.9))
|
574
598
|
end
|
575
599
|
|
576
600
|
def test_hash_no_hashrocket
|
@@ -4857,6 +4881,32 @@ class TestParser < Minitest::Test
|
|
4857
4881
|
%Q{f <<-TABLE do\nTABLE\nend})
|
4858
4882
|
end
|
4859
4883
|
|
4884
|
+
def test_ruby_bug_9669
|
4885
|
+
assert_parses(
|
4886
|
+
s(:def, :a, s(:args, s(:kwarg, :b)), s(:return)),
|
4887
|
+
%Q{def a b:\nreturn\nend},
|
4888
|
+
%q{},
|
4889
|
+
ALL_VERSIONS - %w(1.8 1.9 2.0))
|
4890
|
+
|
4891
|
+
assert_parses(
|
4892
|
+
s(:lvasgn, :o,
|
4893
|
+
s(:hash,
|
4894
|
+
s(:pair, s(:sym, :a), s(:int, 1)))),
|
4895
|
+
%Q{o = {\na:\n1\n}},
|
4896
|
+
%q{},
|
4897
|
+
ALL_VERSIONS - %w(1.8 1.9 2.0))
|
4898
|
+
end
|
4899
|
+
|
4900
|
+
def test_ruby_bug_10279
|
4901
|
+
assert_parses(
|
4902
|
+
s(:hash,
|
4903
|
+
s(:pair, s(:sym, :a),
|
4904
|
+
s(:if, s(:true), s(:int, 42), nil))),
|
4905
|
+
%q{{a: if true then 42 end}},
|
4906
|
+
%q{},
|
4907
|
+
ALL_VERSIONS - %w(1.8 1.9 2.0))
|
4908
|
+
end
|
4909
|
+
|
4860
4910
|
def test_bug_lambda_leakage
|
4861
4911
|
assert_parses(
|
4862
4912
|
s(:begin,
|
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.2.0.pre.
|
4
|
+
version: 2.2.0.pre.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Zotov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-10-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ast
|
@@ -68,22 +68,16 @@ dependencies:
|
|
68
68
|
name: rake
|
69
69
|
requirement: !ruby/object:Gem::Requirement
|
70
70
|
requirements:
|
71
|
-
- - "
|
72
|
-
- !ruby/object:Gem::Version
|
73
|
-
version: '0.9'
|
74
|
-
- - "<"
|
71
|
+
- - "~>"
|
75
72
|
- !ruby/object:Gem::Version
|
76
|
-
version: '
|
73
|
+
version: '10.0'
|
77
74
|
type: :development
|
78
75
|
prerelease: false
|
79
76
|
version_requirements: !ruby/object:Gem::Requirement
|
80
77
|
requirements:
|
81
|
-
- - "
|
82
|
-
- !ruby/object:Gem::Version
|
83
|
-
version: '0.9'
|
84
|
-
- - "<"
|
78
|
+
- - "~>"
|
85
79
|
- !ruby/object:Gem::Version
|
86
|
-
version: '
|
80
|
+
version: '10.0'
|
87
81
|
- !ruby/object:Gem::Dependency
|
88
82
|
name: racc
|
89
83
|
requirement: !ruby/object:Gem::Requirement
|
@@ -334,6 +328,10 @@ files:
|
|
334
328
|
- lib/parser/syntax_error.rb
|
335
329
|
- lib/parser/version.rb
|
336
330
|
- parser.gemspec
|
331
|
+
- test/bug_163/fixtures/input.rb
|
332
|
+
- test/bug_163/fixtures/output.rb
|
333
|
+
- test/bug_163/rewriter.rb
|
334
|
+
- test/bug_163/test_runner_rewrite.rb
|
337
335
|
- test/helper.rb
|
338
336
|
- test/parse_helper.rb
|
339
337
|
- test/racc_coverage_helper.rb
|
@@ -378,6 +376,10 @@ signing_key:
|
|
378
376
|
specification_version: 4
|
379
377
|
summary: A Ruby parser written in pure Ruby.
|
380
378
|
test_files:
|
379
|
+
- test/bug_163/fixtures/input.rb
|
380
|
+
- test/bug_163/fixtures/output.rb
|
381
|
+
- test/bug_163/rewriter.rb
|
382
|
+
- test/bug_163/test_runner_rewrite.rb
|
381
383
|
- test/helper.rb
|
382
384
|
- test/parse_helper.rb
|
383
385
|
- test/racc_coverage_helper.rb
|