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]) # in case of a forward declaration in the same module ignore it since a previous declaration already exists if params[:forward] return node if node.enclosure == self # forward declaration in different scope (other module section in same file or other file) elsif node.is_defined? # multiple full declarations are illegal raise "#{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 "\"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 # in case of a full declaration undo the preceding forward introduction and # replace by full node # (no need to introduce forward declaration since there is a preceding introduction) unless params[:forward] # replace forward node registration node.enclosure.undo_introduction(node) introduce(_intf) end return _intf when IDL::AST::Valuetype node.annotations.concat(params[:annotations]) return node if params[:forward] if node.is_defined? raise "#{node.typename} \"#{node.name}\" is already defined." end if (node.is_abstract? != params[:abstract]) raise "\"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 "#{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 "#{node.name} is already introduced as #{node.typename} #{node.scoped_name}." end