Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
#!/usr/bin/env ruby
gem "parser", "~> 1.4"
require "parser"
require "parser/ruby19"
require "set"
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
File.open("dead_constants.txt", "w") do |f|
processor.dead_constants.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