require 'rrb/script'
module RRB
class GetClassVarOwnerVisitor < Visitor
def initialize(namespace, dumped_info, old_var)
@old_var = old_var
@dumped_info = dumped_info
@my_info = dumped_info[namespace]
@owner = namespace
end
attr_reader :owner
def visit_class(namespace, node)
return false unless node.class_vars.find{|i| i.name == @old_var}
class_name = namespace.nested( node.name )
if @dumped_info[@owner].ancestor_names.include?( class_name )
@owner = class_name
end
end
end
class RenameClassVarVisitor < Visitor
def initialize( owner, dumped_info, old_var, new_var )
@owner = owner
@old_var = old_var
@new_var = new_var
@dumped_info = dumped_info
@result = []
end
attr_reader :result
def check_namespace(namespace)
@dumped_info[namespace].subclass_of?(@owner)
end
def rename_class_var(namespace, node)
if check_namespace(namespace)
node.class_vars.find_all(){|id| id.name == @old_var}.each do |id|
@result << Replacer.new_from_id( id, @new_var )
end
end
end
def visit_method( namespace, node )
rename_class_var(namespace, node)
end
def visit_class_method(namespace, node)
rename_class_var(namespace, node)
end
def visit_class(namespace, node)
rename_class_var(namespace.nested(node.name), node)
end
end
class RenameClassVarCheckVisitor < Visitor
def initialize(owner, dumped_info, old_var, new_var )
@owner = owner
@dumped_info = dumped_info
@old_var = old_var
@new_var = new_var
@result = true
end
attr_reader :result
def check_namespace(namespace)
@dumped_info[namespace].subclass_of?(@owner)
end
def rename_class_var?(namespace, node)
if check_namespace(namespace)
if node.class_vars.any?(){|id| id.name == @new_var}
@error_message = "#{@new_var}: already used by #{namespace.name}"
return false
end
end
return true
end
def visit_method( namespace, node )
if !rename_class_var?(namespace, node)
@result = false
end
end
def visit_class_method(namespace, node)
if !rename_class_var?(namespace, node)
@result = false
end
end
def visit_class(namespace, node)
if !rename_class_var?(namespace.nested( node.name ), node)
@result = false
end
end
end
class ScriptFile
def get_ancestral_cvar_owner( namespace, dumped_info, var )
get_owner = GetClassVarOwnerVisitor.new(namespace, dumped_info, var)
@tree.accept(get_owner)
get_owner.owner
end
def rename_class_var( real_owner, dumped_info, old_var, new_var )
visitor = RenameClassVarVisitor.new(real_owner, dumped_info,
old_var, new_var )
@tree.accept( visitor )
@new_script = RRB.replace_str( @input, visitor.result )
end
def rename_class_var?( namespace, dumped_info, old_var, new_var )
visitor = RenameClassVarCheckVisitor.new(namespace, dumped_info,
old_var, new_var )
@tree.accept( visitor )
@error_message = visitor.error_message unless visitor.result
return visitor.result
end
end
class Script
def get_real_cvar_owner( namespace, var )
@files.inject( namespace ) do |owner,scriptfile|
scriptfile.get_ancestral_cvar_owner( owner, get_dumped_info, var )
end
end
def rename_class_var( namespace, old_var, new_var )
owner = get_real_cvar_owner( namespace, old_var )
@files.each do |scriptfile|
scriptfile.rename_class_var( owner, get_dumped_info,
old_var, new_var )
end
end
def rename_class_var?( namespace, old_var, new_var )
unless RRB.valid_class_var?( new_var )
@error_message = "#{new_var}: not a valid name for class variables"
return false
end
owner = get_real_cvar_owner( namespace, old_var )
@files.each do |scriptfile|
unless scriptfile.rename_class_var?( owner,get_dumped_info,
old_var, new_var )
@error_message = scriptfile.error_message
return false
end
end
return true
end
end
end
syntax highlighted by Code2HTML, v. 0.9.1