class Solargraph::Pin::DelegatedMethod
allows aliasing a method from a different closure (class/module etc).
A DelegatedMethod is a more complicated version of a MethodAlias that
def initialize(method: nil, receiver: nil, name: method&.name, receiver_method_name: name, **splat)
-
receiver_method_name
(String
) -- the method name that will be called on the receiver (defaults to :name). -
name
(String
) -- -
receiver
(Source::Chain, nil
) -- the source code used to resolve the receiver for this delegated method. -
method
(Method, nil
) -- an already resolved method pin.
def initialize(method: nil, receiver: nil, name: method&.name, receiver_method_name: name, **splat) raise ArgumentError, 'either :method or :receiver is required' if (method && receiver) || (!method && !receiver) super(name: name, **splat) @receiver_chain = receiver @resolved_method = method @receiver_method_name = receiver_method_name end
def print_chain(chain)
-
(String)
-
Parameters:
-
chain
(Source::Chain
) --
def print_chain(chain) out = +'' chain.links.each_with_index do |link, index| if index > 0 if Source::Chain::Constant out << '::' unless link.word.start_with?('::') else out << '.' end end out << link.word end out end
def resolvable?(api_map)
-
api_map
(ApiMap
) --
def resolvable?(api_map) resolve_method(api_map) !!@resolved_method end
def resolve_method api_map
-
(Pin::Method, nil)
-
Parameters:
-
api_map
(ApiMap
) --
def resolve_method api_map return if @resolved_method resolver = @receiver_chain.define(api_map, self, []).first unless resolver Solargraph.logger.warn \ "Delegated receiver for #{path} was resolved to nil from `#{print_chain(@receiver_chain)}'" return end receiver_type = resolver.return_type return if receiver_type.undefined? receiver_path, method_scope = if @receiver_chain.constant? # HACK: the `return_type` of a constant is Class<Whatever>, but looking up a method expects # the arguments `"Whatever"` and `scope: :class`. [receiver_type.to_s.sub(/^Class<(.+)>$/, '\1'), :class] else [receiver_type.to_s, :instance] end method_stack = api_map.get_method_stack(receiver_path, @receiver_method_name, scope: method_scope) @resolved_method = method_stack.first end