module Solargraph::RbsMap::Conversions
Functions for converting RBS declarations to Solargraph pins
Constants
- RBS_TO_YARD_TYPE
Public Instance Methods
pins()
click to toggle source
@return [Array<Pin::Base>]
# File lib/solargraph/rbs_map/conversions.rb, line 21 def pins @pins ||= [] end
Private Instance Methods
alias_to_pin(decl, closure)
click to toggle source
# File lib/solargraph/rbs_map/conversions.rb, line 329 def alias_to_pin decl, closure pins.push Solargraph::Pin::MethodAlias.new( name: decl.new_name.to_s, original: decl.old_name.to_s, closure: closure ) end
attr_accessor_to_pin(decl, closure)
click to toggle source
# File lib/solargraph/rbs_map/conversions.rb, line 293 def attr_accessor_to_pin(decl, closure) attr_reader_to_pin(decl, closure) attr_writer_to_pin(decl, closure) end
attr_reader_to_pin(decl, closure)
click to toggle source
# File lib/solargraph/rbs_map/conversions.rb, line 269 def attr_reader_to_pin(decl, closure) pin = Solargraph::Pin::Method.new( name: decl.name.to_s, closure: closure, comments: decl.comment&.string, scope: :instance, attribute: true ) pin.docstring.add_tag(YARD::Tags::Tag.new(:return, '', other_type_to_tag(decl.type))) pins.push pin end
attr_writer_to_pin(decl, closure)
click to toggle source
# File lib/solargraph/rbs_map/conversions.rb, line 281 def attr_writer_to_pin(decl, closure) pin = Solargraph::Pin::Method.new( name: "#{decl.name.to_s}=", closure: closure, comments: decl.comment&.string, scope: :instance, attribute: true ) pin.docstring.add_tag(YARD::Tags::Tag.new(:return, '', other_type_to_tag(decl.type))) pins.push pin end
class_decl_to_pin(decl)
click to toggle source
@param decl [RBS::AST::Declarations::Class] @return [void]
# File lib/solargraph/rbs_map/conversions.rb, line 102 def class_decl_to_pin decl class_pin = Solargraph::Pin::Namespace.new( type: :class, name: decl.name.relative!.to_s, closure: Solargraph::Pin::ROOT_PIN, comments: decl.comment&.string, parameters: decl.type_params.map(&:name).map(&:to_s) ) pins.push class_pin if decl.super_class pins.push Solargraph::Pin::Reference::Superclass.new( closure: class_pin, name: decl.super_class.name.relative!.to_s ) end convert_members_to_pin decl, class_pin end
constant_decl_to_pin(decl)
click to toggle source
@param decl [RBS::AST::Declarations::Constant] @return [void]
# File lib/solargraph/rbs_map/conversions.rb, line 152 def constant_decl_to_pin decl parts = decl.name.relative!.to_s.split('::') if parts.length > 1 name = parts.last closure = pins.select { |pin| pin && pin.path == parts[0..-2].join('::') }.first else name = parts.first closure = Solargraph::Pin::ROOT_PIN end pin = Solargraph::Pin::Constant.new( name: name, closure: closure, comments: decl.comment&.string ) tag = other_type_to_tag(decl.type) # @todo Class or Module? pin.docstring.add_tag(YARD::Tags::Tag.new(:return, '', "Class<#{tag}>")) pins.push pin end
convert_decl_to_pin(decl, closure)
click to toggle source
@param decl [RBS::AST::Declarations::Base] @param closure [Pin::Closure] @return [void]
# File lib/solargraph/rbs_map/conversions.rb, line 34 def convert_decl_to_pin decl, closure cursor = pins.length case decl when RBS::AST::Declarations::Class class_decl_to_pin decl when RBS::AST::Declarations::Interface # STDERR.puts "Skipping interface #{decl.name.relative!}" interface_decl_to_pin decl when RBS::AST::Declarations::Alias type_aliases[decl.name.to_s] = decl when RBS::AST::Declarations::Module module_decl_to_pin decl when RBS::AST::Declarations::Constant constant_decl_to_pin decl end pins[cursor..-1].each do |pin| pin.source = :rbs next unless pin.is_a?(Pin::Namespace) && pin.type == :class next if pins.any? { |p| p.path == "#{pin.path}.new"} pins.push Solargraph::Pin::Method.new( location: nil, closure: pin.closure, name: 'new', comments: pin.comments, scope: :class ) end end
convert_member_to_pin(member, closure, context)
click to toggle source
# File lib/solargraph/rbs_map/conversions.rb, line 68 def convert_member_to_pin member, closure, context case member when RBS::AST::Members::MethodDefinition method_def_to_pin(member, closure) when RBS::AST::Members::AttrReader attr_reader_to_pin(member, closure) when RBS::AST::Members::AttrWriter attr_writer_to_pin(member, closure) when RBS::AST::Members::AttrAccessor attr_accessor_to_pin(member, closure) when RBS::AST::Members::Include include_to_pin(member, closure) when RBS::AST::Members::Prepend prepend_to_pin(member, closure) when RBS::AST::Members::Extend extend_to_pin(member, closure) when RBS::AST::Members::Alias alias_to_pin(member, closure) when RBS::AST::Members::InstanceVariable ivar_to_pin(member, closure) when RBS::AST::Members::Public return Context.new(visibility: :public) when RBS::AST::Members::Private return Context.new(visibility: :private) when RBS::AST::Declarations::Base convert_decl_to_pin(member, closure) else Solargraph.logger.warn "Skipping member #{member.class}" end context end
convert_members_to_pin(decl, closure)
click to toggle source
# File lib/solargraph/rbs_map/conversions.rb, line 63 def convert_members_to_pin decl, closure context = Context.new decl.members.each { |m| context = convert_member_to_pin(m, closure, context) } end
extend_to_pin(decl, closure)
click to toggle source
# File lib/solargraph/rbs_map/conversions.rb, line 322 def extend_to_pin decl, closure pins.push Solargraph::Pin::Reference::Extend.new( name: decl.name.relative!.to_s, closure: closure ) end
include_to_pin(decl, closure)
click to toggle source
# File lib/solargraph/rbs_map/conversions.rb, line 308 def include_to_pin decl, closure pins.push Solargraph::Pin::Reference::Include.new( name: decl.name.relative!.to_s, closure: closure ) end
interface_decl_to_pin(decl)
click to toggle source
@param decl [RBS::AST::Declarations::Interface] @return [void]
# File lib/solargraph/rbs_map/conversions.rb, line 122 def interface_decl_to_pin decl class_pin = Solargraph::Pin::Namespace.new( type: :module, name: decl.name.relative!.to_s, closure: Solargraph::Pin::ROOT_PIN, comments: decl.comment&.string, # HACK: Using :hidden to keep interfaces from appearing in # autocompletion visibility: :hidden ) class_pin.docstring.add_tag(YARD::Tags::Tag.new(:abstract, '(RBS interface)')) pins.push class_pin convert_members_to_pin decl, class_pin end
ivar_to_pin(decl, closure)
click to toggle source
# File lib/solargraph/rbs_map/conversions.rb, line 298 def ivar_to_pin(decl, closure) pin = Solargraph::Pin::InstanceVariable.new( name: decl.name.to_s, closure: closure, comments: decl.comment&.string ) pin.docstring.add_tag(YARD::Tags::Tag.new(:type, '', other_type_to_tag(decl.type))) pins.push pin end
method_def_to_pin(decl, closure)
click to toggle source
@param decl [RBS::AST::Members::MethodDefinition] @param closure [Pin::Closure] @return [void]
# File lib/solargraph/rbs_map/conversions.rb, line 175 def method_def_to_pin decl, closure if decl.instance? pin = Solargraph::Pin::Method.new( name: decl.name.to_s, closure: closure, comments: decl.comment&.string, scope: :instance, signatures: [] ) pin.signatures.concat method_def_to_sigs(decl, pin) pins.push pin if pin.name == 'initialize' pins.push Solargraph::Pin::Method.new( location: pin.location, closure: pin.closure, name: 'new', comments: pin.comments, scope: :class, signatures: pin.signatures ) pins.last.signatures.replace( pin.signatures.map do |p| Pin::Signature.new( p.parameters, ComplexType::SELF ) end ) # @todo Is this necessary? # pin.instance_variable_set(:@visibility, :private) # pin.instance_variable_set(:@return_type, ComplexType::VOID) end end if decl.singleton? pin = Solargraph::Pin::Method.new( name: decl.name.to_s, closure: closure, comments: decl.comment&.string, scope: :class, signatures: [] ) pin.signatures.concat method_def_to_sigs(decl, pin) pins.push pin end end
method_def_to_sigs(decl, pin)
click to toggle source
@param decl [RBS::AST::Members::MethodDefinition] @param pin [Pin::Method]
# File lib/solargraph/rbs_map/conversions.rb, line 223 def method_def_to_sigs decl, pin decl.types.map do |type| parameters, return_type = parts_of_function(type, pin) block = if type.block Pin::Signature.new(*parts_of_function(type.block, pin)) end return_type = ComplexType.try_parse(method_type_to_tag(type)) Pin::Signature.new(parameters, return_type, block) end end
method_type_to_tag(type)
click to toggle source
# File lib/solargraph/rbs_map/conversions.rb, line 345 def method_type_to_tag type if type_aliases.key?(type.type.return_type.to_s) other_type_to_tag(type_aliases[type.type.return_type.to_s].type) else other_type_to_tag type.type.return_type end end
module_decl_to_pin(decl)
click to toggle source
@param decl [RBS::AST::Declarations::Module] @return [void]
# File lib/solargraph/rbs_map/conversions.rb, line 139 def module_decl_to_pin decl module_pin = Solargraph::Pin::Namespace.new( type: :module, name: decl.name.relative!.to_s, closure: Solargraph::Pin::ROOT_PIN, comments: decl.comment&.string ) pins.push module_pin convert_members_to_pin decl, module_pin end
other_type_to_tag(type)
click to toggle source
@return [String]
# File lib/solargraph/rbs_map/conversions.rb, line 354 def other_type_to_tag type if type.is_a?(RBS::Types::Optional) "#{other_type_to_tag(type.type)}, nil" elsif type.is_a?(RBS::Types::Bases::Any) # @todo Not sure what to do with Any yet 'BasicObject' elsif type.is_a?(RBS::Types::Bases::Bool) 'Boolean' elsif type.is_a?(RBS::Types::Tuple) "Array(#{type.types.map { |t| other_type_to_tag(t) }.join(', ')})" elsif type.is_a?(RBS::Types::Literal) "#{type.literal}" elsif type.is_a?(RBS::Types::Union) type.types.map { |t| other_type_to_tag(t) }.join(', ') elsif type.is_a?(RBS::Types::Record) # @todo Better record support 'Hash' elsif type.is_a?(RBS::Types::Bases::Nil) 'nil' elsif type.is_a?(RBS::Types::Bases::Self) 'self' elsif type.is_a?(RBS::Types::Bases::Void) 'void' elsif type.is_a?(RBS::Types::Variable) "param<#{type.name}>" elsif type.is_a?(RBS::Types::ClassInstance) #&& !type.args.empty? base = RBS_TO_YARD_TYPE[type.name.relative!.to_s] || type.name.relative!.to_s params = type.args.map { |a| other_type_to_tag(a) }.reject { |t| t == 'undefined' } return base if params.empty? "#{base}<#{params.join(', ')}>" elsif type.respond_to?(:name) && type.name.respond_to?(:relative!) RBS_TO_YARD_TYPE[type.name.relative!.to_s] || type.name.relative!.to_s else Solargraph.logger.warn "Unrecognized RBS type: #{type.class} #{type}" 'undefined' end end
parts_of_function(type, pin)
click to toggle source
# File lib/solargraph/rbs_map/conversions.rb, line 234 def parts_of_function type, pin parameters = [] arg_num = -1 type.type.required_positionals.each do |param| name = param.name ? param.name.to_s : "arg#{arg_num += 1}" parameters.push Solargraph::Pin::Parameter.new(decl: :arg, name: name, closure: pin, return_type: ComplexType.try_parse(other_type_to_tag(param.type))) end type.type.optional_positionals.each do |param| name = param.name ? param.name.to_s : "arg#{arg_num += 1}" parameters.push Solargraph::Pin::Parameter.new(decl: :optarg, name: name, closure: pin) end if type.type.rest_positionals name = type.type.rest_positionals.name ? type.type.rest_positionals.name.to_s : "arg#{arg_num += 1}" parameters.push Solargraph::Pin::Parameter.new(decl: :restarg, name: name, closure: pin) end type.type.trailing_positionals.each do |param| name = param.name ? param.name.to_s : "arg#{arg_num += 1}" parameters.push Solargraph::Pin::Parameter.new(decl: :arg, name: name, closure: pin) end type.type.required_keywords.each do |orig, _param| name = orig ? orig.to_s : "arg#{arg_num += 1}" parameters.push Solargraph::Pin::Parameter.new(decl: :kwarg, name: name, closure: pin) end type.type.optional_keywords.each do |orig, _param| name = orig ? orig.to_s : "arg#{arg_num += 1}" parameters.push Solargraph::Pin::Parameter.new(decl: :kwoptarg, name: name, closure: pin) end if type.type.rest_keywords name = type.type.rest_keywords.name ? type.type.rest_keywords.name.to_s : "arg#{arg_num += 1}" parameters.push Solargraph::Pin::Parameter.new(decl: :kwrestarg, name: type.type.rest_keywords.name.to_s, closure: pin) end return_type = ComplexType.try_parse(method_type_to_tag(type)) [parameters, return_type] end
prepend_to_pin(decl, closure)
click to toggle source
# File lib/solargraph/rbs_map/conversions.rb, line 315 def prepend_to_pin decl, closure pins.push Solargraph::Pin::Reference::Prepend.new( name: decl.name.relative!.to_s, closure: closure ) end
type_aliases()
click to toggle source
# File lib/solargraph/rbs_map/conversions.rb, line 27 def type_aliases @type_aliases ||= {} end