class Solargraph::Pin::Block

Attributes

receiver[R]

The signature of the method that receives this block.

@return [Parser::AST::Node]

Public Class Methods

new(receiver: nil, args: [], context: nil, **splat) click to toggle source

@param args [Array<Parameter>]

Calls superclass method
# File lib/solargraph/pin/block.rb, line 11
def initialize receiver: nil, args: [], context: nil, **splat
  super(**splat)
  @receiver = receiver
  @context = context
  @parameters = args
end

Public Instance Methods

binder() click to toggle source
# File lib/solargraph/pin/block.rb, line 24
def binder
  @binder || closure.binder
end
parameter_names() click to toggle source

@return [Array<String>]

# File lib/solargraph/pin/block.rb, line 34
def parameter_names
  @parameter_names ||= parameters.map(&:name)
end
parameters() click to toggle source

@return [Array<Parameter>]

# File lib/solargraph/pin/block.rb, line 29
def parameters
  @parameters ||= []
end
rebind(api_map) click to toggle source

@param api_map [ApiMap] @return [void]

# File lib/solargraph/pin/block.rb, line 20
def rebind api_map
  @binder ||= binder_or_nil(api_map)
end

Private Instance Methods

binder_or_nil(api_map) click to toggle source

@param api_map [ApiMap] @return [ComplexType, nil]

# File lib/solargraph/pin/block.rb, line 42
def binder_or_nil api_map
  return nil unless receiver
  word = receiver.children.find { |c| c.is_a?(::Symbol) }.to_s
  return nil unless api_map.rebindable_method_names.include?(word)
  chain = Parser.chain(receiver, location.filename)
  locals = api_map.source_map(location.filename).locals_at(location)
  links_last_word = chain.links.last.word
  if %w[instance_eval instance_exec class_eval class_exec module_eval module_exec].include?(links_last_word)
    return chain.base.infer(api_map, self, locals)
  end
  if 'define_method' == links_last_word and chain.define(api_map, self, locals).first&.path == 'Module#define_method' # change class type to instance type
    if chain.links.size > 1 # Class.define_method
      ty = chain.base.infer(api_map, self, locals)
      return Solargraph::ComplexType.parse(ty.namespace)
    else # define_method without self
      return Solargraph::ComplexType.parse(closure.binder.namespace)
    end
  end
  # other case without early return, read block yieldself tags
  receiver_pin = chain.define(api_map, self, locals).first
  if receiver_pin && receiver_pin.docstring
    ys = receiver_pin.docstring.tag(:yieldself)
    if ys && ys.types && !ys.types.empty?
      return ComplexType.try_parse(*ys.types).qualify(api_map, receiver_pin.context.namespace)
    end
  end
  nil
end