parser 2.3.0.pre.2 → 2.3.0.pre.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +1 -1
- data/CHANGELOG.md +34 -0
- data/README.md +4 -2
- data/Rakefile +1 -0
- data/doc/AST_FORMAT.md +45 -3
- data/lib/parser/all.rb +2 -0
- data/lib/parser/ast/processor.rb +27 -1
- data/lib/parser/builders/default.rb +54 -6
- data/lib/parser/current.rb +9 -0
- data/lib/parser/lexer.rl +87 -64
- data/lib/parser/lexer/literal.rb +1 -1
- data/lib/parser/macruby.y +1 -1
- data/lib/parser/ruby18.y +1 -1
- data/lib/parser/ruby19.y +1 -1
- data/lib/parser/ruby20.y +1 -1
- data/lib/parser/ruby21.y +2 -1
- data/lib/parser/ruby22.y +7 -1
- data/lib/parser/ruby23.y +2363 -0
- data/lib/parser/rubymotion.y +1 -1
- data/lib/parser/runner.rb +7 -0
- data/lib/parser/source/buffer.rb +10 -6
- data/lib/parser/version.rb +1 -1
- data/parser.gemspec +2 -2
- data/test/parse_helper.rb +2 -2
- data/test/test_current.rb +1 -1
- data/test/test_lexer.rb +34 -0
- data/test/test_parser.rb +91 -17
- metadata +6 -5
data/lib/parser/rubymotion.y
CHANGED
@@ -7,7 +7,7 @@ token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
|
|
7
7
|
kUNTIL_MOD kRESCUE_MOD kALIAS kDEFINED klBEGIN klEND k__LINE__
|
8
8
|
k__FILE__ k__ENCODING__ tIDENTIFIER tFID tGVAR tIVAR tCONSTANT
|
9
9
|
tLABEL tCVAR tNTH_REF tBACK_REF tSTRING_CONTENT tINTEGER tFLOAT
|
10
|
-
|
10
|
+
tUPLUS tUMINUS tUMINUS_NUM tPOW tCMP tEQ tEQQ tNEQ
|
11
11
|
tGEQ tLEQ tANDOP tOROP tMATCH tNMATCH tDOT tDOT2 tDOT3 tAREF
|
12
12
|
tASET tLSHFT tRSHFT tCOLON2 tCOLON3 tOP_ASGN tASSOC tLPAREN
|
13
13
|
tLPAREN2 tRPAREN tLPAREN_ARG tLBRACK tLBRACK2 tRBRACK tLBRACE
|
data/lib/parser/runner.rb
CHANGED
@@ -12,6 +12,8 @@ module Parser
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def initialize
|
15
|
+
Parser::Builders::Default.modernize
|
16
|
+
|
15
17
|
@option_parser = OptionParser.new { |opts| setup_option_parsing(opts) }
|
16
18
|
@parser_class = nil
|
17
19
|
@parser = nil
|
@@ -82,6 +84,11 @@ module Parser
|
|
82
84
|
@parser_class = Parser::Ruby22
|
83
85
|
end
|
84
86
|
|
87
|
+
opts.on '--23', 'Parse as Ruby 2.3 would' do
|
88
|
+
require 'parser/ruby23'
|
89
|
+
@parser_class = Parser::Ruby23
|
90
|
+
end
|
91
|
+
|
85
92
|
opts.on '--mac', 'Parse as MacRuby 0.12 would' do
|
86
93
|
require 'parser/macruby'
|
87
94
|
@parser_class = Parser::MacRuby
|
data/lib/parser/source/buffer.rb
CHANGED
@@ -40,6 +40,8 @@ module Parser
|
|
40
40
|
)
|
41
41
|
/x
|
42
42
|
|
43
|
+
NEW_LINE = "\n".freeze
|
44
|
+
|
43
45
|
##
|
44
46
|
# Try to recognize encoding of `string` as Ruby would, i.e. by looking for
|
45
47
|
# magic encoding comment or UTF-8 BOM. `string` can be in any encoding.
|
@@ -173,7 +175,7 @@ module Parser
|
|
173
175
|
raise ArgumentError, 'Source::Buffer is immutable'
|
174
176
|
end
|
175
177
|
|
176
|
-
@source = input.gsub("\r\n",
|
178
|
+
@source = input.gsub("\r\n", NEW_LINE).freeze
|
177
179
|
end
|
178
180
|
|
179
181
|
##
|
@@ -198,7 +200,7 @@ module Parser
|
|
198
200
|
def source_line(lineno)
|
199
201
|
unless @lines
|
200
202
|
@lines = @source.lines.to_a
|
201
|
-
@lines.each { |line| line.chomp!(
|
203
|
+
@lines.each { |line| line.chomp!(NEW_LINE) }
|
202
204
|
|
203
205
|
# If a file ends with a newline, the EOF token will appear
|
204
206
|
# to be one line further than the end of file.
|
@@ -215,7 +217,7 @@ module Parser
|
|
215
217
|
@line_begins, index = [ [ 0, 0 ] ], 1
|
216
218
|
|
217
219
|
@source.each_char do |char|
|
218
|
-
if char ==
|
220
|
+
if char == NEW_LINE
|
219
221
|
@line_begins.unshift [ @line_begins.length, index ]
|
220
222
|
end
|
221
223
|
|
@@ -226,13 +228,15 @@ module Parser
|
|
226
228
|
@line_begins
|
227
229
|
end
|
228
230
|
|
229
|
-
|
230
|
-
|
231
|
+
if [].respond_to?(:bsearch)
|
232
|
+
def line_for(position)
|
231
233
|
# Fast O(log n) variant for Ruby >=2.0.
|
232
234
|
line_begins.bsearch do |line, line_begin|
|
233
235
|
line_begin <= position
|
234
236
|
end
|
235
|
-
|
237
|
+
end
|
238
|
+
else
|
239
|
+
def line_for(position)
|
236
240
|
# Slower O(n) variant for Ruby <2.0.
|
237
241
|
line_begins.find do |line, line_begin|
|
238
242
|
line_begin <= position
|
data/lib/parser/version.rb
CHANGED
data/parser.gemspec
CHANGED
@@ -5,7 +5,7 @@ require File.expand_path('../lib/parser/version', __FILE__)
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
6
|
spec.name = 'parser'
|
7
7
|
spec.version = Parser::VERSION
|
8
|
-
spec.authors = ['
|
8
|
+
spec.authors = ['whitequark']
|
9
9
|
spec.email = ['whitequark@whitequark.org']
|
10
10
|
spec.description = 'A Ruby parser written in pure Ruby.'
|
11
11
|
spec.summary = spec.description
|
@@ -31,7 +31,7 @@ Gem::Specification.new do |spec|
|
|
31
31
|
|
32
32
|
spec.add_development_dependency 'bundler', '~> 1.2'
|
33
33
|
spec.add_development_dependency 'rake', '~> 10.0'
|
34
|
-
spec.add_development_dependency 'racc', '= 1.4.
|
34
|
+
spec.add_development_dependency 'racc', '= 1.4.13'
|
35
35
|
spec.add_development_dependency 'cliver', '~> 0.3.0'
|
36
36
|
|
37
37
|
spec.add_development_dependency 'yard'
|
data/test/parse_helper.rb
CHANGED
@@ -7,11 +7,10 @@ module ParseHelper
|
|
7
7
|
ALL_VERSIONS = %w(1.8)
|
8
8
|
else
|
9
9
|
require 'parser/all'
|
10
|
-
require 'parser/ruby22'
|
11
10
|
require 'parser/macruby'
|
12
11
|
require 'parser/rubymotion'
|
13
12
|
|
14
|
-
ALL_VERSIONS = %w(1.8 1.9 2.0 2.1 2.2 mac ios)
|
13
|
+
ALL_VERSIONS = %w(1.8 1.9 2.0 2.1 2.2 2.3 mac ios)
|
15
14
|
end
|
16
15
|
|
17
16
|
def setup
|
@@ -27,6 +26,7 @@ module ParseHelper
|
|
27
26
|
when '2.0' then parser = Parser::Ruby20.new
|
28
27
|
when '2.1' then parser = Parser::Ruby21.new
|
29
28
|
when '2.2' then parser = Parser::Ruby22.new
|
29
|
+
when '2.3' then parser = Parser::Ruby23.new
|
30
30
|
when 'mac' then parser = Parser::MacRuby.new
|
31
31
|
when 'ios' then parser = Parser::RubyMotion.new
|
32
32
|
else raise "Unrecognized Ruby version #{version}"
|
data/test/test_current.rb
CHANGED
@@ -15,7 +15,7 @@ class TestCurrent < Minitest::Test
|
|
15
15
|
when /^2\.2\.\d+/
|
16
16
|
assert_equal Parser::Ruby22, Parser::CurrentRuby
|
17
17
|
when /^2\.3\.\d+/
|
18
|
-
assert_equal Parser::
|
18
|
+
assert_equal Parser::Ruby23, Parser::CurrentRuby
|
19
19
|
else
|
20
20
|
flunk "Update test_current for #{RUBY_VERSION}"
|
21
21
|
end
|
data/test/test_lexer.rb
CHANGED
@@ -226,6 +226,12 @@ class TestLexer < Minitest::Test
|
|
226
226
|
assert_lex_fname "&", :tAMPER2
|
227
227
|
end
|
228
228
|
|
229
|
+
def test_and_dot
|
230
|
+
@lex.state = :expr_cmdarg
|
231
|
+
|
232
|
+
assert_scanned "&.", :tANDDOT, "&."
|
233
|
+
end
|
234
|
+
|
229
235
|
def test_assoc
|
230
236
|
assert_scanned "=>", :tASSOC, "=>"
|
231
237
|
end
|
@@ -2296,6 +2302,34 @@ class TestLexer < Minitest::Test
|
|
2296
2302
|
end
|
2297
2303
|
end
|
2298
2304
|
|
2305
|
+
#
|
2306
|
+
# Test for 'fluent interface'
|
2307
|
+
#
|
2308
|
+
|
2309
|
+
def test_fluent_dot
|
2310
|
+
assert_scanned("x\n.y",
|
2311
|
+
:tIDENTIFIER, 'x',
|
2312
|
+
:tDOT, '.',
|
2313
|
+
:tIDENTIFIER, 'y')
|
2314
|
+
|
2315
|
+
assert_scanned("x\n .y",
|
2316
|
+
:tIDENTIFIER, 'x',
|
2317
|
+
:tDOT, '.',
|
2318
|
+
:tIDENTIFIER, 'y')
|
2319
|
+
|
2320
|
+
assert_scanned("x # comment\n .y",
|
2321
|
+
:tIDENTIFIER, 'x',
|
2322
|
+
:tDOT, '.',
|
2323
|
+
:tIDENTIFIER, 'y')
|
2324
|
+
end
|
2325
|
+
|
2326
|
+
def test_fluent_and_dot
|
2327
|
+
assert_scanned("x\n&.y",
|
2328
|
+
:tIDENTIFIER, 'x',
|
2329
|
+
:tANDDOT, '&.',
|
2330
|
+
:tIDENTIFIER, 'y')
|
2331
|
+
end
|
2332
|
+
|
2299
2333
|
#
|
2300
2334
|
# Tests for whitespace.
|
2301
2335
|
#
|
data/test/test_parser.rb
CHANGED
@@ -3,6 +3,8 @@
|
|
3
3
|
require 'helper'
|
4
4
|
require 'parse_helper'
|
5
5
|
|
6
|
+
Parser::Builders::Default.modernize
|
7
|
+
|
6
8
|
class TestParser < Minitest::Test
|
7
9
|
include ParseHelper
|
8
10
|
|
@@ -361,15 +363,20 @@ class TestParser < Minitest::Test
|
|
361
363
|
end
|
362
364
|
|
363
365
|
def test_regex_error
|
364
|
-
|
366
|
+
begin
|
367
|
+
Regexp.new("?")
|
368
|
+
rescue RegexpError => e
|
369
|
+
message = e.message
|
370
|
+
end
|
371
|
+
|
365
372
|
assert_diagnoses(
|
366
|
-
[:error, :invalid_regexp, {:message =>
|
373
|
+
[:error, :invalid_regexp, {:message => message}],
|
367
374
|
%q[/?/],
|
368
375
|
%q(~~~ location),
|
369
376
|
ALL_VERSIONS - %w(1.8))
|
370
377
|
|
371
378
|
assert_diagnoses(
|
372
|
-
[:error, :invalid_regexp, {:message =>
|
379
|
+
[:error, :invalid_regexp, {:message => message}],
|
373
380
|
%q[/#{""}?/],
|
374
381
|
%q(~~~~~~~~ location),
|
375
382
|
ALL_VERSIONS - %w(1.8))
|
@@ -3106,20 +3113,20 @@ class TestParser < Minitest::Test
|
|
3106
3113
|
|
3107
3114
|
def test_send_lambda
|
3108
3115
|
assert_parses(
|
3109
|
-
s(:block, s(:
|
3116
|
+
s(:block, s(:lambda),
|
3110
3117
|
s(:args), nil),
|
3111
3118
|
%q{->{ }},
|
3112
|
-
%q{~~
|
3119
|
+
%q{~~ expression (lambda)
|
3113
3120
|
| ^ begin
|
3114
3121
|
| ^ end
|
3115
3122
|
|~~~~~ expression},
|
3116
3123
|
ALL_VERSIONS - %w(1.8))
|
3117
3124
|
|
3118
3125
|
assert_parses(
|
3119
|
-
s(:block, s(:
|
3126
|
+
s(:block, s(:lambda),
|
3120
3127
|
s(:args, s(:restarg)), nil),
|
3121
3128
|
%q{-> * { }},
|
3122
|
-
%q{~~
|
3129
|
+
%q{~~ expression (lambda)
|
3123
3130
|
| ^ begin
|
3124
3131
|
| ^ end
|
3125
3132
|
| ^ expression (args.restarg)
|
@@ -3127,10 +3134,10 @@ class TestParser < Minitest::Test
|
|
3127
3134
|
ALL_VERSIONS - %w(1.8))
|
3128
3135
|
|
3129
3136
|
assert_parses(
|
3130
|
-
s(:block, s(:
|
3137
|
+
s(:block, s(:lambda),
|
3131
3138
|
s(:args), nil),
|
3132
3139
|
%q{-> do end},
|
3133
|
-
%q{~~
|
3140
|
+
%q{~~ expression (lambda)
|
3134
3141
|
| ^^ begin
|
3135
3142
|
| ^^^ end
|
3136
3143
|
|~~~~~~~~~ expression},
|
@@ -3139,12 +3146,12 @@ class TestParser < Minitest::Test
|
|
3139
3146
|
|
3140
3147
|
def test_send_lambda_args
|
3141
3148
|
assert_parses(
|
3142
|
-
s(:block, s(:
|
3149
|
+
s(:block, s(:lambda),
|
3143
3150
|
s(:args,
|
3144
3151
|
s(:arg, :a)),
|
3145
3152
|
nil),
|
3146
3153
|
%q{->(a) { }},
|
3147
|
-
%q{~~
|
3154
|
+
%q{~~ expression (lambda)
|
3148
3155
|
| ^ begin (args)
|
3149
3156
|
| ^ end (args)
|
3150
3157
|
| ^ begin
|
@@ -3153,7 +3160,7 @@ class TestParser < Minitest::Test
|
|
3153
3160
|
ALL_VERSIONS - %w(1.8))
|
3154
3161
|
|
3155
3162
|
assert_parses(
|
3156
|
-
s(:block, s(:
|
3163
|
+
s(:block, s(:lambda),
|
3157
3164
|
s(:args,
|
3158
3165
|
s(:arg, :a)),
|
3159
3166
|
nil),
|
@@ -3164,7 +3171,7 @@ class TestParser < Minitest::Test
|
|
3164
3171
|
|
3165
3172
|
def test_send_lambda_args_shadow
|
3166
3173
|
assert_parses(
|
3167
|
-
s(:block, s(:
|
3174
|
+
s(:block, s(:lambda),
|
3168
3175
|
s(:args,
|
3169
3176
|
s(:arg, :a),
|
3170
3177
|
s(:shadowarg, :foo),
|
@@ -3175,6 +3182,40 @@ class TestParser < Minitest::Test
|
|
3175
3182
|
ALL_VERSIONS - %w(1.8))
|
3176
3183
|
end
|
3177
3184
|
|
3185
|
+
def test_send_lambda_args_noparen
|
3186
|
+
assert_parses(
|
3187
|
+
s(:block, s(:lambda),
|
3188
|
+
s(:args,
|
3189
|
+
s(:kwoptarg, :a, s(:int, 1))),
|
3190
|
+
nil),
|
3191
|
+
%q{-> a: 1 { }},
|
3192
|
+
%q{},
|
3193
|
+
ALL_VERSIONS - %w(1.8 1.9 mac ios))
|
3194
|
+
|
3195
|
+
assert_parses(
|
3196
|
+
s(:block, s(:lambda),
|
3197
|
+
s(:args,
|
3198
|
+
s(:kwarg, :a)),
|
3199
|
+
nil),
|
3200
|
+
%q{-> a: { }},
|
3201
|
+
%q{},
|
3202
|
+
ALL_VERSIONS - %w(1.8 1.9 mac ios 2.0))
|
3203
|
+
end
|
3204
|
+
|
3205
|
+
def test_send_lambda_legacy
|
3206
|
+
Parser::Builders::Default.emit_lambda = false
|
3207
|
+
assert_parses(
|
3208
|
+
s(:block, s(:send, nil, :lambda),
|
3209
|
+
s(:args), nil),
|
3210
|
+
%q{->{ }},
|
3211
|
+
%q{~~ selector (send)
|
3212
|
+
| ^ begin
|
3213
|
+
| ^ end
|
3214
|
+
|~~~~~ expression},
|
3215
|
+
ALL_VERSIONS - %w(1.8))
|
3216
|
+
Parser::Builders::Default.emit_lambda = true
|
3217
|
+
end
|
3218
|
+
|
3178
3219
|
def test_send_call
|
3179
3220
|
assert_parses(
|
3180
3221
|
s(:send, s(:lvar, :foo), :call,
|
@@ -3197,6 +3238,22 @@ class TestParser < Minitest::Test
|
|
3197
3238
|
ALL_VERSIONS - %w(1.8))
|
3198
3239
|
end
|
3199
3240
|
|
3241
|
+
def test_send_conditional
|
3242
|
+
assert_parses(
|
3243
|
+
s(:csend, s(:send, nil, :a), :b),
|
3244
|
+
%q{a&.b},
|
3245
|
+
%q{ ^^ dot},
|
3246
|
+
ALL_VERSIONS - %w(1.8 1.9 2.0 2.1 2.2 ios mac))
|
3247
|
+
end
|
3248
|
+
|
3249
|
+
def test_send_attr_asgn_conditional
|
3250
|
+
assert_parses(
|
3251
|
+
s(:csend, s(:send, nil, :a), :b=, s(:int, 1)),
|
3252
|
+
%q{a&.b = 1},
|
3253
|
+
%q{ ^^ dot},
|
3254
|
+
ALL_VERSIONS - %w(1.8 1.9 2.0 2.1 2.2 ios mac))
|
3255
|
+
end
|
3256
|
+
|
3200
3257
|
def test_lvar_injecting_match
|
3201
3258
|
assert_parses(
|
3202
3259
|
s(:begin,
|
@@ -4724,7 +4781,7 @@ class TestParser < Minitest::Test
|
|
4724
4781
|
s(:pair,
|
4725
4782
|
s(:sym, :x),
|
4726
4783
|
s(:block,
|
4727
|
-
s(:
|
4784
|
+
s(:lambda),
|
4728
4785
|
s(:args),
|
4729
4786
|
s(:block,
|
4730
4787
|
s(:send, nil, :meth),
|
@@ -4999,12 +5056,29 @@ class TestParser < Minitest::Test
|
|
4999
5056
|
assert_parses(
|
5000
5057
|
s(:send, nil, :p,
|
5001
5058
|
s(:block,
|
5002
|
-
s(:
|
5059
|
+
s(:lambda),
|
5003
5060
|
s(:args),
|
5004
5061
|
s(:block, s(:send, nil, :a), s(:args), nil))),
|
5005
5062
|
%q{p ->() do a() do end end},
|
5006
5063
|
%q{},
|
5007
|
-
ALL_VERSIONS - %w(1.8 1.9 mac ios 2.0)) # no 1.9
|
5064
|
+
ALL_VERSIONS - %w(1.8 1.9 mac ios 2.0)) # no 1.9 backport
|
5065
|
+
end
|
5066
|
+
|
5067
|
+
def test_ruby_bug_11380
|
5068
|
+
assert_parses(
|
5069
|
+
s(:block,
|
5070
|
+
s(:send, nil, :p,
|
5071
|
+
s(:block,
|
5072
|
+
s(:lambda),
|
5073
|
+
s(:args),
|
5074
|
+
s(:sym, :hello)),
|
5075
|
+
s(:hash,
|
5076
|
+
s(:pair, s(:sym, :a), s(:int, 1)))),
|
5077
|
+
s(:args),
|
5078
|
+
nil),
|
5079
|
+
%q{p -> { :hello }, a: 1 do end},
|
5080
|
+
%q{},
|
5081
|
+
ALL_VERSIONS - %w(1.8 1.9 mac ios 2.0)) # no 1.9 backport
|
5008
5082
|
end
|
5009
5083
|
|
5010
5084
|
def test_parser_bug_198
|
@@ -5023,7 +5097,7 @@ class TestParser < Minitest::Test
|
|
5023
5097
|
assert_parses(
|
5024
5098
|
s(:begin,
|
5025
5099
|
s(:block,
|
5026
|
-
s(:
|
5100
|
+
s(:lambda),
|
5027
5101
|
s(:args,
|
5028
5102
|
s(:arg, :scope)), nil),
|
5029
5103
|
s(:send, nil, :scope)),
|
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.3.0.pre.
|
4
|
+
version: 2.3.0.pre.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
-
|
7
|
+
- whitequark
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-11-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ast
|
@@ -64,14 +64,14 @@ dependencies:
|
|
64
64
|
requirements:
|
65
65
|
- - '='
|
66
66
|
- !ruby/object:Gem::Version
|
67
|
-
version: 1.4.
|
67
|
+
version: 1.4.13
|
68
68
|
type: :development
|
69
69
|
prerelease: false
|
70
70
|
version_requirements: !ruby/object:Gem::Requirement
|
71
71
|
requirements:
|
72
72
|
- - '='
|
73
73
|
- !ruby/object:Gem::Version
|
74
|
-
version: 1.4.
|
74
|
+
version: 1.4.13
|
75
75
|
- !ruby/object:Gem::Dependency
|
76
76
|
name: cliver
|
77
77
|
requirement: !ruby/object:Gem::Requirement
|
@@ -284,6 +284,7 @@ files:
|
|
284
284
|
- lib/parser/ruby21.y
|
285
285
|
- lib/parser/ruby22.rb
|
286
286
|
- lib/parser/ruby22.y
|
287
|
+
- lib/parser/ruby23.y
|
287
288
|
- lib/parser/rubymotion.rb
|
288
289
|
- lib/parser/rubymotion.y
|
289
290
|
- lib/parser/runner.rb
|