lib/caricature/clr/descriptor.rb in caricature-0.7.5 vs lib/caricature/clr/descriptor.rb in caricature-0.7.6

- old
+ new

@@ -1,160 +1,160 @@ -module Caricature - - # Contains the logic to collect members from a CLR type - module ClrMemberCollector - - attr_reader :class_events, :events - - private - # collects the instance members for a CLR type. - # makes sure it can handle indexers for properties etc. - def build_member_collections(context={}, instance_member=true) - - build_event_collection(context, instance_member) - - mem = [] - mem += build_method_collection(context, instance_member) - mem += build_property_collection(context, instance_member) - mem - end - - def build_property_collection(context, instance_member) - context[:properties].inject([]) do |res, pi| - prop_name = property_name_from(pi) - res << MemberDescriptor.new(prop_name, pi.property_type, instance_member) - res << MemberDescriptor.new("set_Item", nil, instance_member) if prop_name == "get_Item" - res << MemberDescriptor.new("#{prop_name}=", nil, instance_member) if pi.can_write and prop_name != "get_Item" - res - end - end - - def build_method_collection(context, instance_member) - context[:methods].inject([]) do |meths, mi| - meths << MemberDescriptor.new(mi.name.underscore, mi.return_type, instance_member) unless event?(mi.name, instance_member) - meths - end - end - - def build_event_collection(context, instance_member) - context[:events].inject(evts=[]) { |evc, ei| evc << ClrEventDescriptor.new(ei.name, instance_member) } - (instance_member ? @events = evts : @class_events = evts) - end - - # indicates if this member is an event - def event?(name, instance_member) - ((instance_member ? @events : @class_events)||[]).any? { |en| /^(add|remove)_#{en.event_name}/i =~ name } - end - - # gets the property name from the +PropertyInfo+ - # when the property is an indexer it will return +[]+ - def property_name_from(property_info) - return property_info.name.underscore if property_info.get_index_parameters.empty? - "get_Item" - end - - # the binding flags for instance members of a CLR type - def instance_flags - System::Reflection::BindingFlags.public | System::Reflection::BindingFlags.instance - end - - # the binding flags for class members of a CLR type - def class_flags - System::Reflection::BindingFlags.public | System::Reflection::BindingFlags.static - end - - def event_flags - non_public_flag | instance_flags - end - - def class_event_flags - non_public_flag | class_flags - end - - def non_public_flag - System::Reflection::BindingFlags.non_public - end - - end - - class ClrEventDescriptor - - attr_reader :event_name - - def initialize(event_name, instance_member=true) - @event_name, @instance_member = event_name, instance_member - end - - def instance_member? - @instance_member - end - - def add_method_name - "add_#{event_name}" - end - - def remove_method_name - "remove_#{event_name}" - end - - def to_s - "<#{self.class}:#{object_id} @event_name=\"#{event_name}\">" - end - end - - # describes clr interfaces. - # Because CLR interfaces can't have static members this descriptor does not collect any class members - class ClrInterfaceDescriptor < TypeDescriptor - - include ClrMemberCollector - - # collects instance members on this interface - # it will collect properties, methods and property setters - def initialize_instance_members_for(klass) - clr_type = klass.to_clr_type - - context = {} - context[:properties] = clr_type.collect_interface_properties - context[:methods] = clr_type.collect_interface_methods - context[:events] = clr_type.collect_interface_events - - @instance_members = build_member_collections context - end - - # this method is empty because an interface can't have static members - def initialize_class_members_for(klass); end - - end - - - # Describes a CLR class type. it collects the properties and methods on an instance as well as on a static level - class ClrClassDescriptor < TypeDescriptor - - include ClrMemberCollector - - # collects all the instance members of the provided CLR class type - def initialize_instance_members_for(klass) - clr_type = klass.to_clr_type - - context = {} - context[:methods] = clr_type.get_methods(instance_flags) - context[:properties] = clr_type.get_properties(instance_flags) - context[:events] = clr_type.get_events(event_flags) - - @instance_members = build_member_collections context - end - - # collects all the static members of the provided CLR class type - def initialize_class_members_for(klass) - clr_type = klass.to_clr_type - - context = {} - context[:methods] = clr_type.get_methods(class_flags) - context[:properties] = clr_type.get_properties(class_flags) - context[:events] = clr_type.get_events(class_event_flags) - - @class_members = build_member_collections context, false - end - - end - +module Caricature + + # Contains the logic to collect members from a CLR type + module ClrMemberCollector + + attr_reader :class_events, :events + + private + # collects the instance members for a CLR type. + # makes sure it can handle indexers for properties etc. + def build_member_collections(context={}, instance_member=true) + + build_event_collection(context, instance_member) + + mem = [] + mem += build_method_collection(context, instance_member) + mem += build_property_collection(context, instance_member) + mem + end + + def build_property_collection(context, instance_member) + context[:properties].inject([]) do |res, pi| + prop_name = property_name_from(pi) + res << MemberDescriptor.new(prop_name, pi.property_type, instance_member) + res << MemberDescriptor.new("set_Item", nil, instance_member) if prop_name == "get_Item" + res << MemberDescriptor.new("#{prop_name}=", nil, instance_member) if pi.can_write and prop_name != "get_Item" + res + end + end + + def build_method_collection(context, instance_member) + context[:methods].inject([]) do |meths, mi| + meths << MemberDescriptor.new(mi.name.underscore, mi.return_type, instance_member) unless event?(mi.name, instance_member) + meths + end + end + + def build_event_collection(context, instance_member) + context[:events].inject(evts=[]) { |evc, ei| evc << ClrEventDescriptor.new(ei.name, instance_member) } + (instance_member ? @events = evts : @class_events = evts) + end + + # indicates if this member is an event + def event?(name, instance_member) + ((instance_member ? @events : @class_events)||[]).any? { |en| /^(add|remove)_#{en.event_name}/i =~ name } + end + + # gets the property name from the +PropertyInfo+ + # when the property is an indexer it will return +[]+ + def property_name_from(property_info) + return property_info.name.underscore if property_info.get_index_parameters.empty? + "get_Item" + end + + # the binding flags for instance members of a CLR type + def instance_flags + System::Reflection::BindingFlags.public | System::Reflection::BindingFlags.instance + end + + # the binding flags for class members of a CLR type + def class_flags + System::Reflection::BindingFlags.public | System::Reflection::BindingFlags.static + end + + def event_flags + non_public_flag | instance_flags + end + + def class_event_flags + non_public_flag | class_flags + end + + def non_public_flag + System::Reflection::BindingFlags.non_public + end + + end + + class ClrEventDescriptor + + attr_reader :event_name + + def initialize(event_name, instance_member=true) + @event_name, @instance_member = event_name, instance_member + end + + def instance_member? + @instance_member + end + + def add_method_name + "add_#{event_name}" + end + + def remove_method_name + "remove_#{event_name}" + end + + def to_s + "<#{self.class}:#{object_id} @event_name=\"#{event_name}\">" + end + end + + # describes clr interfaces. + # Because CLR interfaces can't have static members this descriptor does not collect any class members + class ClrInterfaceDescriptor < TypeDescriptor + + include ClrMemberCollector + + # collects instance members on this interface + # it will collect properties, methods and property setters + def initialize_instance_members_for(klass) + clr_type = klass.to_clr_type + + context = {} + context[:properties] = clr_type.collect_interface_properties + context[:methods] = clr_type.collect_interface_methods + context[:events] = clr_type.collect_interface_events + + @instance_members = build_member_collections context + end + + # this method is empty because an interface can't have static members + def initialize_class_members_for(klass); end + + end + + + # Describes a CLR class type. it collects the properties and methods on an instance as well as on a static level + class ClrClassDescriptor < TypeDescriptor + + include ClrMemberCollector + + # collects all the instance members of the provided CLR class type + def initialize_instance_members_for(klass) + clr_type = klass.to_clr_type + + context = {} + context[:methods] = clr_type.get_methods(instance_flags) + context[:properties] = clr_type.get_properties(instance_flags) + context[:events] = clr_type.get_events(event_flags) + + @instance_members = build_member_collections context + end + + # collects all the static members of the provided CLR class type + def initialize_class_members_for(klass) + clr_type = klass.to_clr_type + + context = {} + context[:methods] = clr_type.get_methods(class_flags) + context[:properties] = clr_type.get_properties(class_flags) + context[:events] = clr_type.get_events(class_event_flags) + + @class_members = build_member_collections context, false + end + + end + end \ No newline at end of file