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.
@@ -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
- tREGEXP_END tUPLUS tUMINUS tUMINUS_NUM tPOW tCMP tEQ tEQQ tNEQ
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
@@ -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
@@ -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", "\n").freeze
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!("\n") }
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 == "\n"
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
- def line_for(position)
230
- if line_begins.respond_to? :bsearch
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
- else
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
@@ -1,3 +1,3 @@
1
1
  module Parser
2
- VERSION = '2.3.0.pre.2'
2
+ VERSION = '2.3.0.pre.3'
3
3
  end
@@ -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 = ['Peter Zotov']
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.9' # update to 1.4.11 when it's done
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'
@@ -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}"
@@ -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::Ruby22, Parser::CurrentRuby
18
+ assert_equal Parser::Ruby23, Parser::CurrentRuby
19
19
  else
20
20
  flunk "Update test_current for #{RUBY_VERSION}"
21
21
  end
@@ -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
  #
@@ -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
- # The tests work on 1.8, but with a different message.
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 => 'target of repeat operator is not specified: /?/'}],
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 => 'target of repeat operator is not specified: /?/'}],
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(:send, nil, :lambda),
3116
+ s(:block, s(:lambda),
3110
3117
  s(:args), nil),
3111
3118
  %q{->{ }},
3112
- %q{~~ selector (send)
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(:send, nil, :lambda),
3126
+ s(:block, s(:lambda),
3120
3127
  s(:args, s(:restarg)), nil),
3121
3128
  %q{-> * { }},
3122
- %q{~~ selector (send)
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(:send, nil, :lambda),
3137
+ s(:block, s(:lambda),
3131
3138
  s(:args), nil),
3132
3139
  %q{-> do end},
3133
- %q{~~ selector (send)
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(:send, nil, :lambda),
3149
+ s(:block, s(:lambda),
3143
3150
  s(:args,
3144
3151
  s(:arg, :a)),
3145
3152
  nil),
3146
3153
  %q{->(a) { }},
3147
- %q{~~ selector (send)
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(:send, nil, :lambda),
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(:send, nil, :lambda),
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(:send, nil, :lambda),
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(:send, nil, :lambda),
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 mac ios backport
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(:send, nil, :lambda),
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.2
4
+ version: 2.3.0.pre.3
5
5
  platform: ruby
6
6
  authors:
7
- - Peter Zotov
7
+ - whitequark
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-15 00:00:00.000000000 Z
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.9
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.9
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