parser 2.3.0.pre.2 → 2.3.0.pre.3
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/.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
|