Skip to content

Instantly share code, notes, and snippets.

@haileys
Created July 26, 2013 00:07
Show Gist options
  • Save haileys/6084966 to your computer and use it in GitHub Desktop.
Save haileys/6084966 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
gem "parser", "~> 1.4"
require "parser"
require "parser/ruby19"
require "set"
require "active_support/all"
class ConstantDeclarationAndUseProcessor < Parser::AST::Processor
attr_reader :declared, :used
def initialize
@declared = Set.new
@used = Set.new
end
def dead_constants
declared - used
end
def on_const(node)
scope_node, name = *node
used << name
process(scope_node) if scope_node
end
def on_cdecl(node)
scope_node, name, value = *node
declared << name
process(scope_node) if scope_node
process(value) if value
end
def on_class(node)
name_node, superclass_node, body_node = *node
scope_node, name = *name_node
declared << name
process(scope_node) if scope_node
process(superclass_node) if superclass_node
process(body_node) if body_node
end
def on_module(node)
name_node, body_node = *node
scope_node, name = *name_node
declared << name
process(scope_node) if scope_node
process(body_node) if body_node
end
end
files = Dir["{lib,app,config}/**/*.{rb,rake}"].reject { |f| f =~ /generators.*templates/ }
processor = ConstantDeclarationAndUseProcessor.new
files.each do |file|
begin
source = Parser::Source::Buffer.new(file)
source.source = File.read(file)
ast = Parser::Ruby19.new.parse(source)
processor.process(ast)
rescue => e
puts "\e[31;1m#{file}\e[0m"
puts "#{e.class}: #{e.message}"
puts e.backtrace
puts
else
puts "\e[32;1m#{file}\e[0m"
end
$stdout.flush
end
routes = File.read("config/routes.rb")
File.open("dead_constants.txt", "w") do |f|
constants = processor.dead_constants
.reject { |k|
k =~ /Controller$/ and !routes.include?(k.to_s.underscore)
}.reject { |k|
k =~ /Helper$/
}
.each do |sym|
f.puts sym
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment