moduleSteepmoduleServicesclassSignatureHelpProviderMethodCall=TypeInference::MethodCallItem=_=Struct.new(:method_type,:comment,:active_parameter)do# @implements Itemdefparametersarguments=[]#: Array[String]arguments.push(*method_type.type.required_positionals.map(&:to_s))arguments.push(*method_type.type.optional_positionals.map{|p|"?#{p}"})arguments.push("*#{self.method_type.type.rest_positionals}")ifmethod_type.type.rest_positionalsarguments.push(*method_type.type.trailing_positionals.map(&:to_s))arguments.push(*method_type.type.required_keywords.map{|name,param|"#{name}: #{param}"})arguments.push(*method_type.type.optional_keywords.map{|name,param|"?#{name}: #{param}"})arguments.push("**#{method_type.type.rest_keywords}")ifmethod_type.type.rest_keywordsargumentsendendincludeNodeHelperattr_reader:source,:path,:subtyping,:typing,:bufferdefenvsubtyping.factory.envenddefinitialize(source:,subtyping:)@source=source@subtyping=subtyping@buffer=source.bufferenddefrun(line:,column:)nodes=source.find_nodes(line: line,column: column)returnunlessnodestyping=type_check!(line: line,column: column)argument_nodes=[]#: Array[Parser::AST::Node]whiletruenode=nodes.shift()parent=nodes.firstnodeorreturnargument_nodes<<nodeifnode.type==:send||node.type==:csendpos=buffer.loc_to_pos([line,column])begin_loc=(_=node.loc).begin#: Parser::Source::Range?end_loc=(_=node.loc).end#: Parser::Source::Range?ifbegin_loc&&end_locifbegin_loc.end_pos<=pos&&pos<=end_loc.begin_pos# Given position is between open/close parens of args of send nodeifparent&&(parent.type==:block||parent.type==:numblock)&&node.equal?(parent.children[0])send_node=parentelsesend_node=nodeendlast_argument_nodes=last_argument_nodes_for(argument_nodes: argument_nodes,line: line,column: column)returnsignature_help_for(send_node,argument_nodes,last_argument_nodes,typing)endendendendenddeftype_check!(line:,column:)source=self.source.without_unrelated_defs(line: line,column: column)resolver=RBS::Resolver::ConstantResolver.new(builder: subtyping.factory.definition_builder)TypeCheckService.type_check(source: source,subtyping: subtyping,constant_resolver: resolver)enddeflast_argument_nodes_for(argument_nodes:,line:,column:)last=argument_nodes.lastorraisereturnunlesslast.children[2]# No argumentsreturnargument_nodesifargument_nodes.size>1# Cursor is on the last argumentpos=buffer.loc_to_pos([line,column])whiletruepos-=1line,column=buffer.pos_to_loc(pos)nodes=source.find_nodes(line: line,column: column)returnunlessnodesindex=nodes.index{|n|n.type==:send||n.type==:csend}returnnodes[..index]ifindex.to_i>0endenddefsignature_help_for(node,argument,last_argument,typing)call=typing.call_of(node: node)context=typing.context_at(line: node.loc.expression.line,column: node.loc.expression.column)items=[]#: Array[Item]index=nil#: Integer?casecallwhenMethodCall::Typed,MethodCall::Errortype=call.receiver_typeconfig=Interface::Builder::Config.new(self_type: context.self_type,variable_bounds: context.variable_context.upper_bounds)ifshape=subtyping.builder.shape(type,config)shape=shape.public_shapeifprivate_send?(node)ifmethod=shape.methods[call.method_name]method.method_types.each.with_indexdo|method_type,i|defn=method_type.method_decls.to_a[0]&.method_defactive_parameter=active_parameter_for(defn&.type,argument,last_argument,node)items<<Item.new(subtyping.factory.method_type_1(method_type),defn&.comment,active_parameter)ifcall.is_a?(MethodCall::Typed)ifmethod_type.method_decls.intersect?(call.method_decls)index=iendendendendendwhenMethodCall::Untyped,MethodCall::NoMethodErrorreturnend[items,index]enddefactive_parameter_for(method_type,argument_nodes,last_argument_nodes,node)returnunlessmethod_typepositionals=method_type.type.required_positionals.size+method_type.type.optional_positionals.size+(method_type.type.rest_positionals?1:0)+method_type.type.trailing_positionals.sizeifargument_nodes.size==1# Cursor is not on the argument (maybe on comma after argument)return0iflast_argument_nodes.nil?# No argumentscaselast_argument_nodes[-2].typewhen:splatmethod_type.type.required_positionals.size+method_type.type.optional_positionals.size+1ifmethod_type.type.rest_positionalswhen:kwargscaselast_argument_nodes[-3].typewhen:pairargname=last_argument_nodes[-3].children.first.children.firstifmethod_type.type.required_keywords.key?(argname)positionals+method_type.type.required_keywords.keys.index(argname).to_i+1elsifmethod_type.type.optional_keywords.key?(argname)positionals+method_type.type.required_keywords.size+method_type.type.optional_keywords.keys.index(argname).to_i+1elsifmethod_type.type.rest_keywordspositionals+method_type.type.required_keywords.size+method_type.type.optional_keywords.sizeendwhen:kwsplatpositionals+method_type.type.required_keywords.size+method_type.type.optional_keywords.sizeifmethod_type.type.rest_keywordsendelsepos=(node.children[2...]||raise).index{|c|c.location==last_argument_nodes[-2].location}.to_iifmethod_type.type.rest_positionals[pos+1,positionals-1].minelse[pos+1,positionals].minendendelse# Cursor is on the argumentcaseargument_nodes[-2].typewhen:splatmethod_type.type.required_positionals.size+method_type.type.optional_positionals.sizeifmethod_type.type.rest_positionalswhen:kwargsifargument_nodes[-3]caseargument_nodes[-3].typewhen:pairargname=argument_nodes[-3].children.first.children.firstifmethod_type.type.required_keywords.key?(argname)positionals+method_type.type.required_keywords.keys.index(argname).to_ielsifmethod_type.type.optional_keywords.key?(argname)positionals+method_type.type.required_keywords.size+method_type.type.optional_keywords.keys.index(argname).to_ielsifmethod_type.type.rest_keywordspositionals+method_type.type.required_keywords.size+method_type.type.optional_keywords.sizeendwhen:kwsplatpositionals+method_type.type.required_keywords.size+method_type.type.optional_keywords.sizeifmethod_type.type.rest_keywordsendendelsepos=(node.children[2...]||raise).index{|c|c.location==argument_nodes[-2].location}.to_i[pos,positionals-1].minendendendendendend