diff --git a/lib/ripper-tags/parser.rb b/lib/ripper-tags/parser.rb index d69a3db..e8ba548 100644 --- a/lib/ripper-tags/parser.rb +++ b/lib/ripper-tags/parser.rb @@ -103,6 +103,18 @@ def on_dyna_symbol(*args) end end + def on_array(args) + if args.is_a?(Array) && args[0] == :args + args[1..-1] + end + end + + def on_hash(args) + return unless args + + args.select { |arg| arg.is_a?(Array) && arg[0] == :assoc }.map { |_assoc, k, _v| k } + end + undef on_tstring_content def on_tstring_content(str) str @@ -326,7 +338,10 @@ def process(sexp) sexp.each{ |child| process(child) } when Symbol name, *args = sexp - __send__("on_#{name}", *args) unless name.to_s.index("@") == 0 + name = name.to_s + if name.index("@") != 0 && name.index("-@") != 0 + __send__("on_#{name}", *args) + end when String, nil # nothing end @@ -394,6 +409,8 @@ def on_assign(name, rhs, line, *junk) namespace = namespace + parts end + process(rhs) + emit_tag :constant, line, :name => name, :full_name => (namespace + [name]).join('::'), diff --git a/test/test_ripper_tags.rb b/test/test_ripper_tags.rb index 1fcc0ec..07c9dbd 100644 --- a/test/test_ripper_tags.rb +++ b/test/test_ripper_tags.rb @@ -81,6 +81,42 @@ def imethod5 ], tags.map{ |t| t[:full_name] } end + def test_nested_constant_definitions + tags = extract(<<-EOC) + STATUSES = [ + OPEN = 'open', + ] + + DISPLAY_MAPPING = { + CANCELLED = 'cancelled' => 'Cancelled by user', + STARTED = 'started' => 'Started by user', + } + EOC + + assert_equal %w[ + OPEN + STATUSES + CANCELLED + STARTED + DISPLAY_MAPPING + ], tags.map { |t| t[:name] } + + tags.each do |t| + assert_equal t[:name], t[:full_name] + end + end + + def test_doesnt_crash_on_negative_numbers + tags = extract(<<-EOC) + MARSHAL_FIELDS = { + -1 => 16, + 1 => 16, + } + EOC + + assert_equal 1, tags.size + end + def test_extract_namespaced_constant tags = extract(<<-EOC) A::B::C = 1