Class: Laser::Analysis::SpecialMethods::SendMethod
- Inherits:
-
LaserMethod
- Object
- LaserMethod
- Laser::Analysis::SpecialMethods::SendMethod
- Defined in:
- lib/laser/analysis/special_methods/send.rb
Overview
Provides precise analysis of send methods. This is necessary for the analyzer to be able to tell where to look for semantic information when it encounters a call like this:
method = unprovable_condition ? :foo : :bar send(method, 1, 2, 3)
In this case, send() will return the union of whatever foo or bar return, and so on.
This method supports both Kernel#send and Kernel#public_send.
Instance Attribute Summary
Attributes inherited from LaserMethod
#arglist, #arity, #name, #owner, #proc
Instance Method Summary (collapse)
- - (Object) all_target_methods(self_type, arg_type)
- - (Object) dispatch_results(self_type, arg_types, block_type)
-
- (SendMethod) initialize(name, privacy)
constructor
A new instance of SendMethod.
- - (Object) raise_frequency_for_types(self_type, arg_types, block_type)
- - (Object) raise_type_for_types(self_type, arg_types, block_type)
- - (Object) return_type_for_types(self_type, arg_types, block_type)
Methods inherited from LaserMethod
#arg_types_unify_with_annotations?, #argument_annotations, #assign_formals, #been_used!, #cfg_for_types, #check_return_type_against_expectations, #combined_return_type, #dispatched?, #dup, #master_cfg, #overload_for_arg_types, #overloads, #predictable, #refine_arity, #simulate_with_args, #super_method, #valid_arity?, #verify_override_safety, #yield_arity, #yield_type
Methods included from ModuleExtensions
#attr_accessor_with_default, #cattr_accessor, #cattr_accessor_with_default, #cattr_get_and_setter, #cattr_reader, #cattr_writer, #opposite_method
Constructor Details
- (SendMethod) initialize(name, privacy)
A new instance of SendMethod
16 17 18 19 |
# File 'lib/laser/analysis/special_methods/send.rb', line 16 def initialize(name, privacy) super(name, nil) @privacy = privacy end |
Instance Method Details
- (Object) all_target_methods(self_type, arg_type)
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/laser/analysis/special_methods/send.rb', line 21 def all_target_methods(self_type, arg_type) collection = Set[] arg_type.possible_classes.each do |target_klass| if target_klass <= Analysis::ClassRegistry['String'] || target_klass <= Analysis::ClassRegistry['Symbol'] if LaserSingletonClass === target_klass && target_method_name = target_klass.get_instance.to_s self_type.possible_classes.each do |self_class| collection << self_class.instance_method(target_method_name) end else getter = @privacy == :any ? :instance_methods : :public_instance_methods self_type.possible_classes.each do |self_class| self_class.send(getter).each do |method_name| collection << self_class.instance_method(method_name) end end end end end collection end |
- (Object) dispatch_results(self_type, arg_types, block_type)
44 45 46 47 48 49 50 51 |
# File 'lib/laser/analysis/special_methods/send.rb', line 44 def dispatch_results(self_type, arg_types, block_type) methods = all_target_methods(self_type, arg_types[0]) cartesian = [[*arg_types[1..-1], block_type]] ignore_privacy = @privacy == :any results = DispatchResults.new results.add_samples_from_dispatch(methods, self_type, cartesian, ignore_privacy) results end |
- (Object) raise_frequency_for_types(self_type, arg_types, block_type)
69 70 71 72 73 74 75 |
# File 'lib/laser/analysis/special_methods/send.rb', line 69 def raise_frequency_for_types(self_type, arg_types, block_type) if arg_types.size >= 1 dispatch_results(self_type, arg_types, block_type).raise_frequency else ClassRegistry['ArgumentError'].as_type end end |
- (Object) raise_type_for_types(self_type, arg_types, block_type)
61 62 63 64 65 66 67 |
# File 'lib/laser/analysis/special_methods/send.rb', line 61 def raise_type_for_types(self_type, arg_types, block_type) if arg_types.size >= 1 dispatch_results(self_type, arg_types, block_type).raise_type else Frequency::ALWAYS end end |
- (Object) return_type_for_types(self_type, arg_types, block_type)
53 54 55 56 57 58 59 |
# File 'lib/laser/analysis/special_methods/send.rb', line 53 def return_type_for_types(self_type, arg_types, block_type) if arg_types.size >= 1 dispatch_results(self_type, arg_types, block_type).result_type else Types::EMPTY end end |