ruby_parser 3.0.0.a6 → 3.0.0.a7

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of ruby_parser might be problematic. Click here for more details.

data/History.txt CHANGED
@@ -1,3 +1,17 @@
1
+ === 3.0.0.a7 / 2012-09-21
2
+
3
+ * 3 minor enhancements:
4
+
5
+ * Reorganized ruby_parse_extract_error so it will start much faster with a bunch of glob directories
6
+ * RubyParserStuff#process takes optional time arg and raises Timeout::Error if it goes too long. You should rescue that, ya know...
7
+ * ruby_parse_extract_error now checks *.rake and Rakefile on dir scan.
8
+
9
+ * 3 bug fixes:
10
+
11
+ * 1.9: Fixed ternary state tracking so {a:f{f()},b:nil} won't trip up the lexer.
12
+ * Fixed optional values in block args (no20/no21)
13
+ * ruby_parse_extract_error skips non-files. Some asshats put .rb on their dirs. :(
14
+
1
15
  === 3.0.0.a6 / 2012-08-20
2
16
 
3
17
  * 2 minor enhancements:
@@ -33,8 +33,6 @@ class Racc::Parser
33
33
  end
34
34
 
35
35
  def retest_for_errors defs
36
- warn "# retest: #{defs.size}"
37
-
38
36
  parser = self.class.new
39
37
 
40
38
  parser.process(defs.join("\n\n"))
@@ -43,58 +41,62 @@ class Racc::Parser
43
41
  end
44
42
  end
45
43
 
46
- ARGV.replace ARGV.map { |path|
44
+ def expand path
47
45
  if File.directory? path then
48
- Dir.glob File.join path, "**/*.rb"
49
- elsif path =~ /\*\*/ then
50
- Dir.glob path
46
+ Dir.glob File.join path, "**/{*.rb,*.rake,Rakefile}"
51
47
  else
52
- path
48
+ Dir.glob path
53
49
  end
54
- }.flatten.reject { |f|
55
- f =~ /bad_ruby_file/ # I have intentionally bad code in my test dirs
56
- }
50
+ end
57
51
 
58
- ARGV.each do |file|
59
- ruby = file == "-" ? $stdin.read : File.read(file)
52
+ def process_error parser
53
+ defs = parser.extract_defs
60
54
 
61
- begin
62
- $stderr.print "# Validating #{file}: "
63
- parser = Ruby19Parser.new
64
- parser.process(ruby, file)
65
- warn "good"
66
- File.unlink file if $d
67
- rescue StandardError, SyntaxError, Racc::ParseError => e
68
- warn "# error: #{e.message.strip}" unless $q
69
- warn ""
70
- next if $q
71
-
72
- begin
73
- defs = parser.extract_defs
74
-
75
- orig_size = defs.size
76
-
77
- if parser.retest_for_errors defs then
78
- warn "Can't reproduce error with just methods, punting..."
79
- next
80
- end
55
+ orig_size = defs.size
56
+
57
+ if parser.retest_for_errors defs then
58
+ warn "Can't reproduce error with just methods, punting..."
59
+ return
60
+ end
81
61
 
82
- mandatory = defs.pop
83
-
84
- catch :extract_done do
85
- (1..defs.size).each do |perm_size|
86
- defs.combination(perm_size).each do |trial|
87
- trial << mandatory
88
- unless parser.retest_for_errors trial then
89
- puts trial.join "\n"
90
- warn "# reduced repro found!"
91
- throw :extract_done
92
- end
93
- end
62
+ catch :extract_done do
63
+ (1..defs.size).each do |perm_size|
64
+ defs.combination(perm_size).each do |trial|
65
+ unless parser.retest_for_errors trial then
66
+ puts trial.join "\n"
67
+ throw :extract_done
94
68
  end
95
69
  end
96
- rescue RuntimeError, Racc::ParseError => e
97
- warn "# error: #{e.message.strip}"
98
70
  end
99
71
  end
72
+ rescue RuntimeError, Racc::ParseError => e
73
+ warn "# error: #{e.message.strip}"
74
+ end
75
+
76
+ def process file
77
+ ruby = file == "-" ? $stdin.read : File.read(file)
78
+
79
+ $stderr.print "# Validating #{file}: "
80
+ parser = Ruby19Parser.new
81
+ parser.process(ruby, file)
82
+ warn "good"
83
+ File.unlink file if $d
84
+ rescue StandardError, SyntaxError, Racc::ParseError => e
85
+ warn ""
86
+ warn "# error: #{e.message.strip}" unless $q
87
+ warn ""
88
+ return if $q
89
+
90
+ process_error parser
91
+ rescue Timeout::Error
92
+ warn "TIMEOUT parsing #{file}. Skipping."
93
+ end
94
+
95
+ $stdout.sync = true
96
+
97
+ ARGV.each do |path|
98
+ expand(path).each do |file|
99
+ next unless File.file? file # omg... why would you name a dir support.rb?
100
+ process file
101
+ end
100
102
  end
data/lib/ruby19_parser.rb CHANGED
@@ -2593,7 +2593,7 @@ racc_reduce_table = [
2593
2593
  3, 266, :_reduce_527,
2594
2594
  3, 309, :_reduce_528,
2595
2595
  3, 310, :_reduce_529,
2596
- 1, 267, :_reduce_530,
2596
+ 1, 267, :_reduce_none,
2597
2597
  3, 267, :_reduce_531,
2598
2598
  1, 307, :_reduce_532,
2599
2599
  3, 307, :_reduce_533,
@@ -5881,16 +5881,12 @@ def _reduce_528(val, _values, result)
5881
5881
  end
5882
5882
 
5883
5883
  def _reduce_529(val, _values, result)
5884
- raise "no20: #{val.inspect}"
5884
+ result = self.assignable val[0], val[2]
5885
5885
 
5886
5886
  result
5887
5887
  end
5888
5888
 
5889
- def _reduce_530(val, _values, result)
5890
- raise "no21: #{val.inspect}"
5891
-
5892
- result
5893
- end
5889
+ # reduce 530 omitted
5894
5890
 
5895
5891
  def _reduce_531(val, _values, result)
5896
5892
  raise "no22: #{val.inspect}"
data/lib/ruby19_parser.y CHANGED
@@ -1920,13 +1920,10 @@ keyword_variable: kNIL { result = s(:nil) }
1920
1920
 
1921
1921
  f_block_opt: tIDENTIFIER tEQL primary_value
1922
1922
  {
1923
- raise "no20: #{val.inspect}"
1923
+ result = self.assignable val[0], val[2]
1924
1924
  }
1925
1925
 
1926
1926
  f_block_optarg: f_block_opt
1927
- {
1928
- raise "no21: #{val.inspect}"
1929
- }
1930
1927
  | f_block_optarg tCOMMA f_block_opt
1931
1928
  {
1932
1929
  raise "no22: #{val.inspect}"
data/lib/ruby_lexer.rb CHANGED
@@ -16,7 +16,7 @@ class RubyLexer
16
16
  attr_accessor :command_start
17
17
  attr_accessor :cmdarg
18
18
  attr_accessor :cond
19
- attr_accessor :tern
19
+ attr_accessor :tern # TODO: rename ternary damnit... wtf
20
20
  attr_accessor :nest
21
21
 
22
22
  ESC_RE = /\\([0-7]{1,3}|x[0-9a-fA-F]{1,2}|M-[^\\]|(C-|c)[^\\]|[^0-7xMCc])/
@@ -711,6 +711,7 @@ class RubyLexer
711
711
  elsif src.scan(/[\]\)\}]/) then
712
712
  cond.lexpop
713
713
  cmdarg.lexpop
714
+ tern.lexpop
714
715
  self.lex_state = :expr_end
715
716
  self.yacc_value = src.matched
716
717
  result = {
@@ -718,7 +719,6 @@ class RubyLexer
718
719
  "]" => :tRBRACK,
719
720
  "}" => :tRCURLY
720
721
  }[src.matched]
721
- self.tern.lexpop if [:tRBRACK, :tRCURLY].include?(result)
722
722
  return result
723
723
  elsif src.scan(/\.\.\.?|,|![=~]?/) then
724
724
  self.lex_state = :expr_beg
@@ -1295,6 +1295,10 @@ class RubyLexer
1295
1295
  is_arg? and space_seen and c !~ /\s/
1296
1296
  end
1297
1297
 
1298
+ def is_label_possible? command_state
1299
+ (lex_state == :expr_beg && !command_state) || is_arg?
1300
+ end
1301
+
1298
1302
  def yylex_paren19
1299
1303
  if is_beg? then
1300
1304
  result = :tLPAREN
@@ -1358,15 +1362,11 @@ class RubyLexer
1358
1362
  end
1359
1363
 
1360
1364
  unless self.tern.is_in_state
1361
- if (lex_state == :expr_beg && (ruby18 || !command_state)) ||
1362
- lex_state == :expr_arg ||
1363
- lex_state == :expr_cmdarg then
1365
+ if is_label_possible? command_state then
1364
1366
  colon = src.scan(/:/)
1365
1367
 
1366
- if colon && src.peek(1) != ":"
1367
- src.unscan
1368
+ if colon && src.peek(1) != ":" then
1368
1369
  self.lex_state = :expr_beg
1369
- src.scan(/:/)
1370
1370
  self.yacc_value = [token, src.lineno]
1371
1371
  return :tLABEL
1372
1372
  end
@@ -1413,6 +1413,9 @@ class RubyLexer
1413
1413
  end
1414
1414
  end
1415
1415
 
1416
+ # TODO:
1417
+ # if (mb == ENC_CODERANGE_7BIT && lex_state != EXPR_DOT) {
1418
+
1416
1419
  self.lex_state =
1417
1420
  if is_beg? || lex_state == :expr_dot || is_arg? then
1418
1421
  if command_state then
@@ -3,6 +3,7 @@ require 'racc/parser'
3
3
  require 'sexp'
4
4
  require 'strscan'
5
5
  require 'ruby_lexer'
6
+ require "timeout"
6
7
 
7
8
  def d o
8
9
  $stderr.puts o.inspect
@@ -78,7 +79,7 @@ class RPStringScanner < StringScanner
78
79
  end
79
80
 
80
81
  module RubyParserStuff
81
- VERSION = '3.0.0.a6' unless constants.include? "VERSION" # SIGH
82
+ VERSION = '3.0.0.a7' unless constants.include? "VERSION" # SIGH
82
83
 
83
84
  attr_accessor :lexer, :in_def, :in_single, :file
84
85
  attr_reader :env, :comments
@@ -190,8 +191,8 @@ module RubyParserStuff
190
191
 
191
192
  def block_args19 val, id
192
193
  # HACK OMG THIS CODE IS SOOO UGLY! CLEAN ME
193
- untested = %w[1 2 3 4 7 9 10 11 12 14]
194
- raise "no block_args19 #{id}" if untested.include? id
194
+ untested = %w[1 2 3 4 7 9 10 12 14]
195
+ raise "no block_args19 #{id} #{val.inspect}" if untested.include? id
195
196
 
196
197
  r = s(:array)
197
198
 
@@ -213,6 +214,8 @@ module RubyParserStuff
213
214
  }
214
215
  when :block_arg then
215
216
  r << s(:lasgn, :"&#{v.last}")
217
+ when :lasgn then
218
+ r << s(:masgn, s(:array, v))
216
219
  when :masgn then
217
220
  r << v
218
221
  else
@@ -899,29 +902,36 @@ module RubyParserStuff
899
902
  lhs
900
903
  end
901
904
 
902
- def process(str, file = "(string)")
903
- raise "bad val: #{str.inspect}" unless String === str
905
+ ##
906
+ # Parse +str+ at path +file+ and return a sexp. Raises
907
+ # Timeout::Error if it runs for more than +time+ seconds.
904
908
 
905
- str.lines.first(2).find { |s| s[/^# encoding: (.+)/, 1] }
906
- encoding = $1
909
+ def process(str, file = "(string)", time = 10)
910
+ Timeout.timeout time do
911
+ raise "bad val: #{str.inspect}" unless String === str
907
912
 
908
- str = str.dup
913
+ str.lines.first(2).find { |s| s[/^# encoding: (.+)/, 1] }
914
+ encoding = $1
909
915
 
910
- if encoding then
911
- if defined?(Encoding) then
912
- str.force_encoding(encoding).encode! "utf-8"
913
- else
914
- warn "Skipping magic encoding comment"
916
+ str = str.dup
917
+
918
+ if encoding then
919
+ if defined?(Encoding) then
920
+ str.force_encoding(encoding).encode! "utf-8"
921
+ else
922
+ warn "Skipping magic encoding comment"
923
+ end
915
924
  end
916
- end
917
925
 
918
- self.file = file
919
- self.lexer.src = str
926
+ self.file = file
927
+ self.lexer.src = str
920
928
 
921
- @yydebug = ENV.has_key? 'DEBUG'
929
+ @yydebug = ENV.has_key? 'DEBUG'
922
930
 
923
- do_parse
931
+ do_parse
932
+ end
924
933
  end
934
+
925
935
  alias :parse :process
926
936
 
927
937
  def remove_begin node
@@ -1189,10 +1189,40 @@ class TestRuby19Parser < RubyParserTestCase
1189
1189
  assert_parse rb, pt
1190
1190
  end
1191
1191
 
1192
+ def test_block_arg_optional
1193
+ rb = "a { |b = 1| }"
1194
+ pt = s(:iter,
1195
+ s(:call, nil, :a),
1196
+ s(:masgn, s(:array, s(:lasgn, :b, s(:lit, 1)))))
1197
+
1198
+ assert_parse rb, pt
1199
+ end
1200
+
1201
+ def test_zomg_sometimes_i_hate_this_project
1202
+ rb = <<-RUBY
1203
+ {
1204
+ a: lambda { b ? c() : d },
1205
+ e: nil,
1206
+ }
1207
+ RUBY
1208
+
1209
+ pt = s(:hash,
1210
+ s(:lit, :a),
1211
+ s(:iter,
1212
+ s(:call, nil, :lambda),
1213
+ nil,
1214
+ s(:if, s(:call, nil, :b), s(:call, nil, :c), s(:call, nil, :d))),
1215
+
1216
+ s(:lit, :e),
1217
+ s(:nil))
1218
+
1219
+ assert_parse rb, pt
1220
+ end
1221
+
1192
1222
  # def test_pipe_semicolon # HACK
1193
1223
  # rb = "a.b do | ; c | end"
1194
1224
  # pt = s(:iter, s(:call, s(:call, nil, :a), :b), 0)
1195
- #
1225
+ #
1196
1226
  # assert_parse rb, pt
1197
1227
  # end
1198
1228
 
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_parser
3
3
  version: !ruby/object:Gem::Version
4
- hash: 4039646929
4
+ hash: 1069898451
5
5
  prerelease: 6
6
6
  segments:
7
7
  - 3
8
8
  - 0
9
9
  - 0
10
10
  - a
11
- - 6
12
- version: 3.0.0.a6
11
+ - 7
12
+ version: 3.0.0.a7
13
13
  platform: ruby
14
14
  authors:
15
15
  - Ryan Davis
@@ -38,7 +38,7 @@ cert_chain:
38
38
  FBHgymkyj/AOSqKRIpXPhjC6
39
39
  -----END CERTIFICATE-----
40
40
 
41
- date: 2012-08-20 00:00:00 Z
41
+ date: 2012-09-21 00:00:00 Z
42
42
  dependencies:
43
43
  - !ruby/object:Gem::Dependency
44
44
  name: sexp_processor
@@ -63,11 +63,11 @@ dependencies:
63
63
  requirements:
64
64
  - - ~>
65
65
  - !ruby/object:Gem::Version
66
- hash: 3
66
+ hash: 1
67
67
  segments:
68
68
  - 3
69
- - 2
70
- version: "3.2"
69
+ - 3
70
+ version: "3.3"
71
71
  type: :development
72
72
  version_requirements: *id002
73
73
  - !ruby/object:Gem::Dependency
metadata.gz.sig CHANGED
Binary file