Class: IDL::AST::Interface

Inherits:
Derivable show all
Defined in:
lib/ridl/node.rb,
lib/ridl/node.rb

Overview

Derivable

Constant Summary collapse

DEFINABLE =
[IDL::AST::Const, IDL::AST::Operation, IDL::AST::Attribute,
IDL::AST::Struct, IDL::AST::Union, IDL::AST::Typedef, IDL::AST::Enum, IDL::AST::Enumerator]

Instance Attribute Summary collapse

Attributes inherited from Leaf

#annotations, #enclosure, #intern, #name, #prefix, #scopes

Instance Method Summary collapse

Methods inherited from Derivable

#has_ancestor?, #search_self, #search_self_before_derived

Methods inherited from Node

#define, #introduce, #is_definable?, #match_members, #replace_prefix, #resolve, #select_members, #undo_introduction, #walk_members

Methods inherited from Leaf

#has_annotations?, #is_template?, #lm_name, #lm_scopes, #replace_prefix, #repository_id, #resolve, #scoped_lm_name, #scoped_name, #set_repo_id, #set_repo_version, #typename, #unescaped_name

Constructor Details

#initialize(_name, _enclosure, params) ⇒ Interface

Returns a new instance of Interface.



974
975
976
977
978
979
980
981
982
983
984
# File 'lib/ridl/node.rb', line 974

def initialize(_name, _enclosure, params)
  super(_name, _enclosure)
  @bases = []
  @resolved_bases = []
  @defined = !params[:forward]
  @abstract = params[:abstract]
  @pseudo = params[:pseudo]
  @local = params[:local]
  @idltype = IDL::Type::Interface.new(self)
  add_bases(params[:inherits] || [])
end

Instance Attribute Details

#basesObject (readonly)

Returns the value of attribute bases.



972
973
974
# File 'lib/ridl/node.rb', line 972

def bases
  @bases
end

#idltypeObject (readonly)

Returns the value of attribute idltype.



972
973
974
# File 'lib/ridl/node.rb', line 972

def idltype
  @idltype
end

Instance Method Details

#add_bases(inherits_) ⇒ Object



1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
# File 'lib/ridl/node.rb', line 1034

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::NodeType) && tc.is_node?(IDL::AST::Interface))
        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 rtc.node.is_local? and not self.is_local?
        raise "#{typename} #{scoped_lm_name} cannot inherit from 'local' #{tc.node.typename} #{tc.node.scoped_lm_name}"
      end
      if rtc.node.is_pseudo? and not self.is_pseudo?
        raise "#{typename} #{scoped_lm_name} cannot inherit from 'pseudo' #{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 self.is_local? and rtc.node.is_abstract?
        raise "'local' #{typename} #{scoped_lm_name} cannot inherit from 'abstract' #{tc.node.typename} #{tc.node.scoped_lm_name}"
      end
      if self.has_base?(rtc.node)
        raise "#{typename} #{scoped_lm_name} cannot inherit from #{tc.node.typename} #{tc.node.scoped_lm_name} multiple times"
      end

      # check if we indirectly derive from this base multiple times (which is ok; no further need to check)
      unless @resolved_bases.any? { |b| b.has_ancestor?(rtc.node) }
        # this is a new base so we need to check for member redefinition/ambiguity
        new_op_att_ = []
        rtc.node.walk_members do |m|
          new_op_att_ << m if m.is_a?(IDL::AST::Operation) || m.is_a?(IDL::AST::Attribute)
        end
        if new_op_att_.any? { |n| n_ = self.search_self(n.name)
 n_.is_a?(IDL::AST::Operation) || n_.is_a?(IDL::AST::Attribute) }
          raise "#{typename} #{scoped_lm_name} cannot inherit from #{tc.node.typename} #{tc.node.scoped_lm_name} because of duplicated operations/attributes"
        end
        # no need to check for duplicate member names; this inheritance is ok
      end
      @resolved_bases << rtc.node
    end
    @bases << tc.node
  end
end

#ancestorsObject



1087
1088
1089
# File 'lib/ridl/node.rb', line 1087

def ancestors
  @resolved_bases
end

#attributes(include_bases = false, traversed = nil) ⇒ Object



1097
1098
1099
1100
1101
# File 'lib/ridl/node.rb', line 1097

def attributes(include_bases = false, traversed = nil)
  atts = @children.find_all { |c| c.is_a?(IDL::AST::Attribute) }
  atts.concat(base_attributes(traversed || [])) if include_bases
  atts
end

#has_base?(_base) ⇒ Boolean

Returns:

  • (Boolean)


1083
1084
1085
# File 'lib/ridl/node.rb', line 1083

def has_base?(_base)
  @resolved_bases.any? { |b| b == _base.idltype.resolved_type.node }
end

#instantiate(instantiation_context, _enclosure) ⇒ Object



1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
# File 'lib/ridl/node.rb', line 1001

def instantiate(instantiation_context, _enclosure)
  _params = {
    forward: self.is_forward?,
    abstract: self.is_abstract?,
    pseudo: self.is_pseudo?,
    local: self.is_local?,
    inherits: self.concrete_bases(instantiation_context)
  }
  # instantiate concrete interface def and validate
  # concrete bases
  super(instantiation_context, _enclosure, _params)
end

#is_abstract?Boolean

Returns:

  • (Boolean)


1014
1015
1016
# File 'lib/ridl/node.rb', line 1014

def is_abstract?
  @abstract
end

#is_defined?Boolean

Returns:

  • (Boolean)


1026
1027
1028
# File 'lib/ridl/node.rb', line 1026

def is_defined?
  @defined
end

#is_forward?Boolean

Returns:

  • (Boolean)


1030
1031
1032
# File 'lib/ridl/node.rb', line 1030

def is_forward?
  not @defined
end

#is_local?Boolean

Returns:

  • (Boolean)


1018
1019
1020
# File 'lib/ridl/node.rb', line 1018

def is_local?
  @local
end

#is_pseudo?Boolean

Returns:

  • (Boolean)


1022
1023
1024
# File 'lib/ridl/node.rb', line 1022

def is_pseudo?
  @pseudo
end

#marshal_dumpObject



986
987
988
# File 'lib/ridl/node.rb', line 986

def marshal_dump
  super() << @bases << @resolved_bases << @defined << @abstract << @local << @pseudo << @idltype
end

#marshal_load(vars) ⇒ Object



990
991
992
993
994
995
996
997
998
999
# File 'lib/ridl/node.rb', line 990

def marshal_load(vars)
  @idltype = vars.pop
  @pseudo = vars.pop
  @local = vars.pop
  @abstract = vars.pop
  @defined = vars.pop
  @resolved_bases = vars.pop
  @bases = vars.pop
  super(vars)
end

#operations(include_bases = false, traversed = nil) ⇒ Object



1091
1092
1093
1094
1095
# File 'lib/ridl/node.rb', line 1091

def operations(include_bases = false, traversed = nil)
  ops = @children.find_all { |c| c.is_a?(IDL::AST::Operation) }
  ops.concat(base_operations(traversed || [])) if include_bases
  ops
end

#redefine(node, params) ⇒ Object



1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
# File 'lib/ridl/node.rb', line 1103

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
    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)
    @children << newnode # add overriding child
    return newnode
  end
end