class Solargraph::Source::Chain::Call
Attributes
@return [Array<Chain>]
@return [String]
Public Class Methods
@param word [String] @param arguments [Array<Chain>] @param with_block [Boolean] True if the chain is inside a block @param head [Boolean] True if the call is the start of its chain
# File lib/solargraph/source/chain/call.rb, line 16 def initialize word, arguments = [], with_block = false @word = word @arguments = arguments @with_block = with_block end
Public Instance Methods
@param api_map [ApiMap] @param name_pin [Pin::Base] @param locals [Array<Pin::Base>]
# File lib/solargraph/source/chain/call.rb, line 29 def resolve api_map, name_pin, locals return super_pins(api_map, name_pin) if word == 'super' found = if head? locals.select { |p| p.name == word } else [] end return inferred_pins(found, api_map, name_pin.context, locals) unless found.empty? # @param [ComplexType::UniqueType] pins = name_pin.binder.each_unique_type.flat_map do |context| api_map.get_method_stack(context.namespace, word, scope: context.scope) end return [] if pins.empty? inferred_pins(pins, api_map, name_pin.context, locals) end
# File lib/solargraph/source/chain/call.rb, line 22 def with_block? @with_block end
Private Instance Methods
@param arguments [Array<Chain>] @param signature [Pin::Signature] @return [Boolean]
# File lib/solargraph/source/chain/call.rb, line 187 def arguments_match arguments, signature parameters = signature.parameters argcount = arguments.length parcount = parameters.length parcount -= 1 if !parameters.empty? && parameters.last.block? return false if signature.block? && !with_block? return false if argcount < parcount && !(argcount == parcount - 1 && parameters.last.restarg?) true end
@param docstring [YARD::Docstring] @param context [ComplexType] @return [ComplexType]
# File lib/solargraph/source/chain/call.rb, line 175 def extra_return_type docstring, context if docstring.has_tag?(:return_single_parameter) #&& context.subtypes.one? return context.subtypes.first || ComplexType::UNDEFINED elsif docstring.has_tag?(:return_value_parameter) && context.value_types.one? return context.value_types.first end nil end
@param pins [Array<Pin::Base>] @param api_map [ApiMap] @param context [ComplexType] @param locals [Pin::LocalVariable] @return [Array<Pin::Base>]
# File lib/solargraph/source/chain/call.rb, line 52 def inferred_pins pins, api_map, context, locals result = pins.map do |p| next p unless p.is_a?(Pin::Method) overloads = p.signatures # next p if overloads.empty? type = ComplexType::UNDEFINED overloads.each do |ol| next unless arguments_match(arguments, ol) # next if ol.parameters.last && ol.parameters.last.first.start_with?('&') && ol.parameters.last.last.nil? && !with_block? match = true arguments.each_with_index do |arg, idx| param = ol.parameters[idx] if param.nil? match = false unless ol.parameters.any?(&:restarg?) break end atype = arg.infer(api_map, Pin::ProxyType.anonymous(context), locals) # @todo Weak type comparison # unless atype.tag == param.return_type.tag || api_map.super_and_sub?(param.return_type.tag, atype.tag) unless param.return_type.undefined? || atype.name == param.return_type.name || api_map.super_and_sub?(param.return_type.name, atype.name) match = false break end end if match type = extra_return_type(p.docstring, context) break if type type = with_params(ol.return_type.self_to(context.to_s), context).qualify(api_map, context.namespace) if ol.return_type.defined? type ||= ComplexType::UNDEFINED end break if type.defined? end next p.proxy(type) if type.defined? type = extra_return_type(p.docstring, context) if type next Solargraph::Pin::Method.new( location: p.location, closure: p.closure, name: p.name, comments: "@return [#{context.subtypes.first.to_s}]", scope: p.scope, visibility: p.visibility, parameters: p.parameters, node: p.node ) end if p.is_a?(Pin::Method) && !p.macros.empty? result = process_macro(p, api_map, context, locals) next result unless result.return_type.undefined? elsif !p.directives.empty? result = process_directive(p, api_map, context, locals) next result unless result.return_type.undefined? end p end result.map do |pin| if pin.path == 'Class#new' && context.tag != 'Class' pin.proxy(ComplexType.try_parse(context.namespace)) else next pin if pin.return_type.undefined? selfy = pin.return_type.self_to(context.tag) selfy == pin.return_type ? pin : pin.proxy(selfy) end end end
@param pin [Pin] @param macro [YARD::Tags::MacroDirective] @param api_map [ApiMap] @param context [ComplexType] @param locals [Array<Pin::Base>] @return [Pin::ProxyType]
# File lib/solargraph/source/chain/call.rb, line 152 def inner_process_macro pin, macro, api_map, context, locals vals = arguments.map{ |c| Pin::ProxyType.anonymous(c.infer(api_map, pin, locals)) } txt = macro.tag.text.clone if txt.empty? && macro.tag.name named = api_map.named_macro(macro.tag.name) txt = named.tag.text.clone if named end i = 1 vals.each do |v| txt.gsub!(/\$#{i}/, v.context.namespace) i += 1 end docstring = Solargraph::Source.parse_docstring(txt).to_docstring tag = docstring.tag(:return) unless tag.nil? || tag.types.nil? return Pin::ProxyType.anonymous(ComplexType.try_parse(*tag.types)) end Pin::ProxyType.anonymous(ComplexType::UNDEFINED) end
@param pin [Pin::Method] @param api_map [ApiMap] @param context [ComplexType] @param locals [Pin::Base] @return [Pin::ProxyType]
# File lib/solargraph/source/chain/call.rb, line 136 def process_directive pin, api_map, context, locals pin.directives.each do |dir| macro = api_map.named_macro(dir.tag.name) next if macro.nil? result = inner_process_macro(pin, macro, api_map, context, locals) return result unless result.return_type.undefined? end Pin::ProxyType.anonymous ComplexType::UNDEFINED end
@param pin [Pin::Method] @param api_map [ApiMap] @param context [ComplexType] @param locals [Pin::Base] @return [Pin::Base]
# File lib/solargraph/source/chain/call.rb, line 123 def process_macro pin, api_map, context, locals pin.macros.each do |macro| result = inner_process_macro(pin, macro, api_map, context, locals) return result unless result.return_type.undefined? end Pin::ProxyType.anonymous(ComplexType::UNDEFINED) end
@param api_map [ApiMap] @param name_pin [Pin::Base] @return [Array<Pin::Base>]
# File lib/solargraph/source/chain/call.rb, line 200 def super_pins api_map, name_pin pins = api_map.get_method_stack(name_pin.namespace, name_pin.name, scope: name_pin.context.scope) pins.reject{|p| p.path == name_pin.path} end
@param type [ComplexType] @param context [ComplexType]
# File lib/solargraph/source/chain/call.rb, line 207 def with_params type, context return type unless type.to_s.include?('$') ComplexType.try_parse(type.to_s.gsub('$', context.value_types.map(&:tag).join(', ')).gsub('<>', '')) end