require 'rrb/script'
require 'pp'
module RRB
module ConstResolver
def resolve_const(dumped_info,ns,const)
if const[0,2] == "::"
return const[2..-1]
end
ans = dumped_info.resolve_const( Namespace.new(ns), const.split('::')[0] )
if ans == nil then
return nil
else
if ans == Namespace::Toplevel then
return "#{const}"
else
return "#{ans.name}::#{const}"
end
end
end
def class_of(constname)
if constname[0,2]=="::"
ret = constname.split('::')[1..-2].join('::')
else
ret = constname.split('::')[0..-2].join('::')
end
if ret==""
"Object"
else
ret
end
end
end
class RenameConstantVisitor < Visitor
include ConstResolver
def initialize(dumped_info, old_const, new_const_body)
if old_const[0,2] != '::' then
@old_const = old_const
else
@old_const = old_const[2..-1]
end
@old_const_body = old_const.split("::")[-1]
@new_const_body = new_const_body
@dumped_info = dumped_info
@result = []
end
attr_reader :result
def visit_node(namespace, node)
ns = namespace.name
#if node isn't method definition..
if ModuleNode === node || SingletonClassNode === node
ns << '::' unless namespace.name==""
ns << node.name_id.name
end
node.consts.each do |constinfo|
next if constinfo.body.name != @old_const_body
if constinfo.toplevel?
used_const = constinfo.name
else
used_const = resolve_const(@dumped_info, ns, constinfo.name)
end
if used_const == @old_const then
id = constinfo.body
@result << Replacer.new_from_id( id, @new_const_body)
end
end
end
def visit_class(namespace, node)
if resolve_const(@dumped_info, namespace.name, node.name_id.name) == @old_const
@result << Replacer.new_from_id( node.name_id, @new_const_body )
end
end
end
class ScriptFile
def rename_constant(dumped_info, old_const, new_const)
visitor = RenameConstantVisitor.new(dumped_info, old_const, new_const)
@tree.accept(visitor)
@new_script = RRB.replace_str(@input, visitor.result)
end
end
class Script
def rename_constant(old_const, new_const)
@files.each do |scriptfile|
scriptfile.rename_constant(get_dumped_info, old_const, new_const)
end
end
def rename_constant?(old_const, new_const)
unless RRB.valid_const?(new_const)
@error_message = "#{new_const} is not a valid name for constants"
return false
end
ns = Namespace.new(old_const)
result_namespace = get_dumped_info.resolve_const( ns.chop, new_const )
unless result_namespace.nil? then
@error_message = "#{result_namespace.name}::#{new_const} is already defined"
return false
end
return true
end
end
end
syntax highlighted by Code2HTML, v. 0.9.1