lib/caricature/clr/descriptor.rb in caricature-0.7.2 vs lib/caricature/clr/descriptor.rb in caricature-0.7.5
- old
+ new
@@ -1,47 +1,108 @@
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 collect_members_from(meths, properties, instance_member=true)
+ # 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)
- mem = []
- mem += meths.collect do |mi|
- MemberDescriptor.new(mi.name.underscore, mi.return_type, instance_member)
- end
- properties.each do |pi|
- prop_name = property_name_from(pi)
- mem << MemberDescriptor.new(prop_name, pi.property_type, instance_member)
- mem << MemberDescriptor.new("__setitem__", nil, instance_member) if prop_name == "__getitem__"
- mem << MemberDescriptor.new("#{prop_name}=", nil, instance_member) if pi.can_write and prop_name != "__getitem__"
- end
- mem
+ 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
- # 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?
- "__getitem__"
- 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
+ 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
@@ -49,14 +110,16 @@
# 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
- properties = clr_type.collect_interface_properties
- methods = clr_type.collect_interface_methods
+ context = {}
+ context[:properties] = clr_type.collect_interface_properties
+ context[:methods] = clr_type.collect_interface_methods
+ context[:events] = clr_type.collect_interface_events
- @instance_members = collect_members_from methods, properties
+ @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
@@ -70,23 +133,27 @@
# collects all the instance members of the provided CLR class type
def initialize_instance_members_for(klass)
clr_type = klass.to_clr_type
- methods = clr_type.get_methods(instance_flags)
- properties = clr_type.get_properties(instance_flags)
+ 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 = collect_members_from methods, properties
+ @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
- methods = clr_type.get_methods(class_flags)
- properties = clr_type.get_properties(class_flags)
+ 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 = collect_members_from methods, properties, false
+ @class_members = build_member_collections context, false
end
end
end
\ No newline at end of file