class IDL::AST::Module

def redefine(node, params)

def redefine(node, params)
  case node
  when IDL::AST::Include
    if node.enclosure == self
      return node
    else
      _inc = IDL::AST::Include.new(node.name, self, params)
      _inc.annotations.concat(params[:annotations])
      @children << _inc
      return _inc
    end
  when IDL::AST::Module
    # Module reopening
    _anchor = node.has_anchor? ? node.anchor : node
    _anchor.annotations.concat(params.delete(:annotations))
    _last = _anchor.find_last
    _params = params.merge({ :anchor => _anchor, :prefix => node.prefix })
    _next = IDL::AST::Module.new(node.name, self, _params)
    _last.set_next(_next)
    @children << _next
    return _next
  when IDL::AST::Interface
    node.annotations.concat(params[:annotations])
    return node if params[:forward]
    if node.is_defined?
      raise RuntimeError, "#{node.typename} \"#{node.name}\" is already defined."
    end
    if (node.is_abstract? != params[:abstract]) || (node.is_local? != params[:local]) || (node.is_pseudo? != params[:pseudo])
      raise RuntimeError, "\"attributes are not the same: \"#{node.name}\"."
    end
    _intf = IDL::AST::Interface.new(node.name, self, params)
    _intf.annotations.concat(node.annotations)
    _intf.prefix = node.prefix
    _intf.instance_variable_set(:@repo_ver, node.instance_variable_get(:@repo_ver))
    _intf.instance_variable_set(:@repo_id, node.instance_variable_get(:@repo_id))
    @children << _intf
    # replace forward node registration
    node.enclosure.undo_introduction(node)
    introduce(_intf)
    return _intf
  when IDL::AST::Valuetype
    node.annotations.concat(params[:annotations])
    return node if params[:forward]
    if node.is_defined?
      raise RuntimeError, "#{node.typename} \"#{node.name}\" is already defined."
    end
    if (node.is_abstract? != params[:abstract])
      raise RuntimeError, "\"attributes are not the same: \"#{node.name}\"."
    end
    _new_node = node.class.new(node.name, self, params)
    _new_node.annotations.concat(node.annotations)
    _new_node.prefix = node.prefix
    _new_node.instance_variable_set(:@repo_ver, node.instance_variable_get(:@repo_ver))
    _new_node.instance_variable_set(:@repo_id, node.instance_variable_get(:@repo_id))
    @children << _new_node
    # replace forward node registration
    node.enclosure.undo_introduction(node)
    introduce(_new_node)
    return _new_node
  when IDL::AST::Struct, IDL::AST::Union
    node.annotations.concat(params[:annotations])
    return node if params[:forward]
    if node.is_defined?
      raise RuntimeError, "#{node.typename} \"#{node.name}\" is already defined."
    end
    _new_node = node.class.new(node.name, self, params)
    _new_node.annotations.concat(node.annotations)
    _new_node.prefix = node.prefix
    _new_node.instance_variable_set(:@repo_ver, node.instance_variable_get(:@repo_ver))
    _new_node.instance_variable_set(:@repo_id, node.instance_variable_get(:@repo_id))
    node.switchtype = params[:switchtype] if node.is_a?(IDL::AST::Union)
    @children << _new_node
    # replace forward node registration
    node.enclosure.undo_introduction(node)
    introduce(_new_node)
    return _new_node
  end
  raise RuntimeError,
        "#{node.name} is already introduced as #{node.typename} #{node.scoped_name}."
end