Dan42

Search for generic forwarding in rubygems

Sep 10th, 2019
111
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/bin/env ruby
  2.  
  3. require "pathname"
  4. require "set"
  5.  
  6. Dir.chdir("/opt/ruby/2.7/lib/ruby/gems/2.7.0/")
  7.  
  8. list = Pathname.new("gems.rblist")
  9. if ARGV.delete("--refresh") or !list.exist? or list.mtime < Time.now-86400
  10.   system "find gems/ -name '*.rb' > #{list}"
  11. end
  12.  
  13. ugems = Set.new
  14. ufiles = Set.new
  15. ulines = Set.new
  16.  
  17. list.readlines.each do |file| file.chomp!
  18.   _,gem,path = file.split("/",3)
  19.   gemname = gem[/\A(.*)-/,1]
  20.   path =~ /\Alib\// or next
  21.  
  22.   ruby = File.read(file)
  23.   ruby.scan(%r(^( *)def (?:\w+\.)?(?:\w+[!?]?)(.*end *$|(?:.*)(?:\n.*)*?\n\1end))) do
  24.     dfn,body = $&.split("\n",2)
  25.     dfn,body = dfn.split(/(?<=[\);])/,2) if body.nil?
  26.     if dfn !~ /\*\*\w+/ and dfn =~ /\*(\w+)/
  27.       var = $1
  28.       delegation = body.lines.grep(/\w+[!?]?[ \(]([^,()]+, *)*\*#{var}\b/).first
  29.       delegation ||= x=body.lines.grep(/\*#{var}\b/).first
  30.       if delegation
  31.         red=';31' if x
  32.         puts "\e[1#{red}m#{file}\e[0m", dfn, delegation||"\e[37;2m#{body}\e[0m"
  33.         ugems << gemname
  34.         ufiles << file
  35.         ulines << file+":"+dfn
  36.       end
  37.     end
  38.   end
  39. end
  40.  
  41. printf "%d matches in %d files of %d gems\n", ulines.size, ufiles.size, ugems.size
  42.  
  43. #with *args in dfn and body
  44. #lib:   1949 matches in 1095 files of 225 gems
  45. #others: 256 matches in 167 files of 63 gems
  46.  
  47. #with *args in dfn only
  48. #lib:   2899 matches in 2014 files of 433 gems
RAW Paste Data