class IDL::AST::Valuetype

Constants

DEFINABLE

Attributes

bases[R]
idltype[R]
interfaces[R]

Public Class Methods

new(_name, _enclosure, params) click to toggle source
Calls superclass method IDL::AST::Node::new
# File lib/ridl/node.rb, line 1706
def initialize(_name, _enclosure, params)
  super(_name, _enclosure)
  @bases = []
  @resolved_bases = []
  @interfaces = []
  @resolved_interfaces = []
  @defined = false
  @recursive = false
  @forward = params[:forward] ? true : false
  @abstract = params[:abstract]
  @idltype = IDL::Type::Valuetype.new(self)
  complete_definition(params)
end

Public Instance Methods

add_bases(inherits_) click to toggle source
# File lib/ridl/node.rb, line 1848
def add_bases(inherits_)
  inherits_.each do |tc|
    unless tc.is_a?(IDL::Type::ScopedName) && tc.is_node?(IDL::AST::TemplateParam)
      unless (tc.is_a?(IDL::Type::ScopedName) && tc.is_node?(IDL::AST::Valuetype))
        raise "invalid inheritance identifier for #{typename} #{scoped_lm_name}: #{tc.typename}"
      end

      rtc = tc.resolved_type
      if rtc.node.has_ancestor?(self)
        raise "circular inheritance detected for #{typename} #{scoped_lm_name}: #{tc.node.scoped_lm_name} is descendant"
      end
      unless rtc.node.is_defined?
        raise "#{typename} #{scoped_lm_name} cannot inherit from forward declared #{tc.node.typename} #{tc.node.scoped_lm_name}"
      end
      if self.is_abstract? and not rtc.node.is_abstract?
        raise "'abstract' #{typename} #{scoped_lm_name} cannot inherit from non-'abstract' #{tc.node.typename} #{tc.node.scoped_lm_name}"
      end
      if (not self.is_custom?) and rtc.node.is_custom?
        raise "non-'custom' #{typename} #{scoped_lm_name} cannot inherit from 'custom' #{tc.node.typename} #{tc.node.scoped_lm_name}"
      end
      if @resolved_bases.include?(rtc.node)
        raise "#{typename} #{scoped_lm_name} cannot inherit from #{tc.node.typename} #{tc.node.scoped_lm_name} multiple times"
      end

      if (not rtc.node.is_abstract?) and !@bases.empty?
        raise "concrete basevalue #{tc.node.typename} #{tc.node.scoped_lm_name} MUST " +
              "be first and only non-abstract in inheritance list for #{typename} #{scoped_lm_name}"
      end
      @resolved_bases << rtc.node
    end
    @bases << tc.node
  end
end
add_interfaces(iflist_) click to toggle source
# File lib/ridl/node.rb, line 1882
def add_interfaces(iflist_)
  iflist_.each do |if_|
    unless if_.is_a?(IDL::Type::ScopedName) && if_.is_node?(IDL::AST::TemplateParam)
      unless (if_.is_a?(IDL::Type::ScopedName) && if_.is_node?(IDL::AST::Interface))
        raise "invalid support identifier for #{typename} #{scoped_lm_name}: #{if_.typename}"
      end

      rif_ = if_.resolved_type
      ### @@TODO@@ further validation
      if (not rif_.node.is_abstract?) and !@interfaces.empty?
        raise "concrete interface '#{rif_.node.scoped_lm_name}' inheritance not allowed for #{typename} #{scoped_lm_name}. Valuetypes can only inherit (support) a single concrete interface."
      end
      if (not rif_.node.is_abstract?) && (not is_interface_compatible?(rif_.node))
        raise "#{typename} #{scoped_lm_name} cannot support concrete interface #{rif_.node.scoped_lm_name} because it does not derive from inherited concrete interfaces"
      end

      @resolved_interfaces << rif_.node
    end
    @interfaces << if_.node
  end
end
complete_definition(params) click to toggle source
# File lib/ridl/node.rb, line 1720
def complete_definition(params)
  unless params[:forward]
    @custom = params[:custom] || false
    _inherits = params[:inherits] || {}
    _base = _inherits[:base] || {}
    @truncatable = _base[:truncatable] || false
    if @custom && @truncatable
        raise "'truncatable' attribute *not* allowed for 'custom' #{typename} #{scoped_lm_name}"
    end

    add_bases(_base[:list] || [])
    add_interfaces(_inherits[:supports] || [])
  end
end
define(_type, _name, *args) click to toggle source
Calls superclass method IDL::AST::Node#define
# File lib/ridl/node.rb, line 1916
def define(_type, _name, *args)
  if self.is_abstract? && [IDL::AST::StateMember, IDL::AST::Initializer].include?(_type)
    raise "cannot define statemember #{_name} on abstract #{typename} #{scoped_lm_name}"
  end

  super(_type, _name, *args)
end
defined=(f) click to toggle source
# File lib/ridl/node.rb, line 1792
def defined=(f)
  @defined = f
end
has_ancestor?(n) click to toggle source
# File lib/ridl/node.rb, line 1904
def has_ancestor?(n)
  @resolved_bases.include?(n.idltype.resolved_type.node) || @resolved_bases.any? { |b| b.has_ancestor?(n) }
end
has_concrete_base?() click to toggle source
# File lib/ridl/node.rb, line 1830
def has_concrete_base?
  (not @resolved_bases.empty?) and (not @resolved_bases.first.is_abstract?)
end
has_operations_or_attributes?(include_intf = true) click to toggle source
# File lib/ridl/node.rb, line 1944
def has_operations_or_attributes?(include_intf = true)
  @children.any? { |c| c.is_a?(IDL::AST::Operation) || c.is_a?(IDL::AST::Attribute) } ||
    @resolved_bases.any? { |b| b.has_operations_or_attributes? } ||
    (include_intf &&
     @resolved_interfaces.any? { |intf| !intf.operations(true).empty? || !intf.attributes(true).empty? })
end
initializers() click to toggle source
# File lib/ridl/node.rb, line 1940
def initializers
  @children.find_all { |c| c.is_a?(IDL::AST::Initializer) }
end
instantiate(instantiation_context, _enclosure) click to toggle source
Calls superclass method IDL::AST::Leaf#instantiate
# File lib/ridl/node.rb, line 1758
def instantiate(instantiation_context, _enclosure)
  _params = {
    forward: self.is_forward?,
    abstract: self.is_abstract?,
    custom: self.is_custom?,
    inherits: {
      base: {
        truncatable: self.is_truncatable?,
        list: self.concrete_bases(instantiation_context)
      },
      supports: self.concrete_interfaces(instantiation_context)
    }
  }
  inst = super(instantiation_context, _enclosure, _params)
  inst.defined = true
  inst
end
interface_members() click to toggle source
# File lib/ridl/node.rb, line 1936
def interface_members
  @children.find_all { |c| c.is_a?(IDL::AST::Operation) or c.is_a?(IDL::AST::Attribute) }
end
is_abstract?() click to toggle source
# File lib/ridl/node.rb, line 1776
def is_abstract?
  @abstract
end
is_custom?() click to toggle source
# File lib/ridl/node.rb, line 1780
def is_custom?
  @custom
end
is_defined?() click to toggle source
# File lib/ridl/node.rb, line 1788
def is_defined?
  @defined
end
is_forward?() click to toggle source
# File lib/ridl/node.rb, line 1796
def is_forward?
  @forward
end
is_interface_compatible?(n) click to toggle source
# File lib/ridl/node.rb, line 1908
def is_interface_compatible?(n)
  if @resolved_interfaces.empty? || @resolved_interfaces.first.is_abstract?
    @resolved_bases.all? { |b| b.is_interface_compatible?(n) }
  else
    n.idltype.resolved_type.node.has_ancestor?(@interfaces.first)
  end
end
is_local?(recurstk = []) click to toggle source
# File lib/ridl/node.rb, line 1808
def is_local?(recurstk = [])
  # not local if forward decl or recursion detected
  return false if is_forward? || recurstk.include?(self)

  recurstk.push self # track root node to detect recursion
  ret = state_members.any? { |m| m.is_local?(recurstk) }
  recurstk.pop
  ret
end
is_recursive?() click to toggle source
# File lib/ridl/node.rb, line 1800
def is_recursive?
  @recursive
end
is_truncatable?() click to toggle source
# File lib/ridl/node.rb, line 1784
def is_truncatable?
  @truncatable
end
marshal_dump() click to toggle source
Calls superclass method IDL::AST::Node#marshal_dump
# File lib/ridl/node.rb, line 1735
def marshal_dump
  super() << @bases << @resolved_bases <<
             @interfaces << @resolved_interfaces <<
             @defined << @recursive <<
             @forward << @abstract <<
             @custom << @truncatable << @idltype
end
marshal_load(vars) click to toggle source
Calls superclass method IDL::AST::Node#marshal_load
# File lib/ridl/node.rb, line 1743
def marshal_load(vars)
  @idltype = vars.pop
  @truncatable = vars.pop
  @custom = vars.pop
  @abstract = vars.pop
  @forward = vars.pop
  @recursive = vars.pop
  @defined = vars.pop
  @resolved_interfaces = vars.pop
  @interfaces = vars.pop
  @resolved_bases = vars.pop
  @bases = vars.pop
  super(vars)
end
modifier() click to toggle source
# File lib/ridl/node.rb, line 1818
def modifier
  if is_abstract?
    :abstract
  elsif is_custom?
    :custom
  elsif is_truncatable?
    :truncatable
  else
    :none
  end
end
recursive=(f) click to toggle source
# File lib/ridl/node.rb, line 1804
def recursive=(f)
  @recursive = f
end
redefine(node, params) click to toggle source
# File lib/ridl/node.rb, line 1951
def redefine(node, params)
  if node.enclosure == self
    case node
    when IDL::AST::Struct, IDL::AST::Union
      if node.is_defined?
        raise "#{node.typename} \"#{node.name}\" is already defined."
      end

      node.annotations.concat(params[:annotations])

      _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
    else
      raise "#{node.typename} \"#{node.name}\" is already defined."
    end
  end

  case node
  when IDL::AST::Operation, IDL::AST::Attribute, IDL::AST::StateMember, IDL::AST::Initializer
    raise "#{node.typename} '#{node.scoped_lm_name}' cannot be overridden."
  else
    newnode = node.class.new(node.name, self, params)
    newnode.annotations.concat(params[:annotations])
    introduce(newnode)
    return newnode
  end
end
state_members() click to toggle source
# File lib/ridl/node.rb, line 1932
def state_members
  @children.find_all { |c| c.is_a?(IDL::AST::StateMember) }
end
supports_abstract_interface?() click to toggle source
# File lib/ridl/node.rb, line 1838
def supports_abstract_interface?
  @resolved_interfaces.any? { |intf| intf.is_abstract? }
end
supports_concrete_interface?() click to toggle source
# File lib/ridl/node.rb, line 1834
def supports_concrete_interface?
  !(@resolved_interfaces.empty? || @resolved_interfaces.first.is_abstract?)
end
truncatable_ids() click to toggle source
# File lib/ridl/node.rb, line 1842
def truncatable_ids
  ids = [self.repository_id]
  ids.concat(@resolved_bases.first.truncatable_ids) if self.has_concrete_base? && self.is_truncatable?
  ids
end
walk_members() { |c| ... } click to toggle source
# File lib/ridl/node.rb, line 1924
def walk_members
  @children.each { |c| yield(c) unless c.is_a?(IDL::AST::StateMember) or
                                       c.is_a?(IDL::AST::Operation) or
                                       c.is_a?(IDL::AST::Attribute) or
                                       c.is_a?(IDL::AST::Initializer)
  }
end

Protected Instance Methods

concrete_bases(instantiation_context) click to toggle source
# File lib/ridl/node.rb, line 2001
def concrete_bases(instantiation_context)
  # collect all bases and resolve any template param types
  @bases.collect do |_base|
    IDL::AST::TemplateParam.concrete_param(instantiation_context, _base)
  end
end
concrete_interfaces(instantiation_context) click to toggle source
# File lib/ridl/node.rb, line 2008
def concrete_interfaces(instantiation_context)
  @interfaces.collect do |_intf|
    IDL::AST::TemplateParam.concrete_param(instantiation_context, _intf)
  end
end
resolved_bases() click to toggle source
# File lib/ridl/node.rb, line 1997
def resolved_bases
  @resolved_bases
end
walk_members_for_copy() { |c| ... } click to toggle source
# File lib/ridl/node.rb, line 1993
def walk_members_for_copy
  @children.each { |c| yield(c) }
end