class IDL::Delegator

def walk_member(m, w)

def walk_member(m, w)
  case m
  when IDL::AST::Include
    unless m.is_preprocessed?
      if @expand_includes
        if m.is_defined?
          w.enter_include(m)
          m.walk_members { |cm| walk_member(cm, w) }
          w.leave_include(m)
        end
      else
        w.visit_include(m)
      end
    end
  when IDL::AST::Porttype, IDL::AST::TemplateModule
    # these are template types and do not generally generate
    # code by themselves but only when 'instantiated' (used)
    # in another type
  when IDL::AST::Module
    w.enter_module(m)
    m.walk_members { |cm| walk_member(cm, w) }
    w.leave_module(m)
  when IDL::AST::Interface
    if m.is_forward?
      w.declare_interface(m)
    else
      w.enter_interface(m)
      m.walk_members { |cm| walk_member(cm, w) }
      w.leave_interface(m)
    end
  when IDL::AST::Home
    _te = w.respond_to?(:enter_home)
    _tl = w.respond_to?(:leave_home)
    return unless _te || _tl
    w.enter_home(m) if _te
    m.walk_members { |cm| walk_member(cm, w) }
    w.leave_home(m) if _tl
  when IDL::AST::Component
    if m.is_forward?
      w.declare_component(m) if w.respond_to?(:declare_component)
    else
      _te = w.respond_to?(:enter_component)
      _tl = w.respond_to?(:leave_component)
      return unless _te || _tl
      w.enter_component(m) if _te
      m.walk_members { |cm| walk_member(cm, w) }
      w.leave_component(m) if _tl
    end
  when IDL::AST::Connector
    _te = w.respond_to?(:enter_connector)
    _tl = w.respond_to?(:leave_connector)
    return unless _te || _tl
    w.enter_connector(m) if _te
    m.walk_members { |cm| walk_member(cm, w) }
    w.leave_connector(m) if _tl
  when IDL::AST::Port
    w.visit_port(m) if w.respond_to?(:visit_port)
  when IDL::AST::Valuebox
    w.visit_valuebox(m)
  when IDL::AST::Valuetype, IDL::AST::Eventtype
    if m.is_forward?
      w.declare_valuetype(m)
    else
      w.enter_valuetype(m)
      m.walk_members { |cm| walk_member(cm, w) }
      w.leave_valuetype(m)
    end
  when IDL::AST::Finder
    w.visit_finder(m) if w.respond_to?(:visit_finder)
  when IDL::AST::Initializer
    w.visit_factory(m) if w.respond_to?(:visit_factory)
  when IDL::AST::Const
    w.visit_const(m)
  when IDL::AST::Operation
    w.visit_operation(m)
  when IDL::AST::Attribute
    w.visit_attribute(m)
  when IDL::AST::Exception
    w.enter_exception(m)
    m.walk_members { |cm| walk_member(cm, w) }
    w.leave_exception(m)
  when IDL::AST::Struct
    if m.is_forward?
      w.declare_struct(m)
    else
      w.enter_struct(m)
      m.walk_members { |cm| walk_member(cm, w) }
      w.leave_struct(m)
    end
  when IDL::AST::Union
    if m.is_forward?
      w.declare_union(m)
    else
      w.enter_union(m)
      m.walk_members { |cm| walk_member(cm, w) }
      w.leave_union(m)
    end
  when IDL::AST::Typedef
    w.visit_typedef(m)
  when IDL::AST::Enum
    w.visit_enum(m)
  when IDL::AST::Enumerator
    w.visit_enumerator(m)
  when IDL::AST::BitMask
    w.visit_bitmask(m)
  when IDL::AST::BitValue
    w.visit_bitvalue(m)
  when IDL::AST::BitSet
    w.visit_bitset(m)
  when IDL::AST::BitField
    w.visit_bitfield(m)
  else
    raise "Invalid IDL member type for walkthrough: #{m.class.name}"
  end
end