class Solargraph::ComplexType
A container for type data based on YARD type tags.
Constants
- BOOLEAN
- NIL
- ROOT
- SELF
- SYMBOL
- UNDEFINED
- VOID
Public Class Methods
new(types = [UniqueType::UNDEFINED])
click to toggle source
@param types [Array<UniqueType>]
# File lib/solargraph/complex_type.rb, line 14 def initialize types = [UniqueType::UNDEFINED] @items = types.uniq(&:to_s) end
Private Class Methods
parse(*strings, partial: false)
click to toggle source
Parse type strings into a ComplexType
.
@example
ComplexType.parse 'String', 'Foo', 'nil' #=> [String, Foo, nil]
@note
The `partial` parameter is used to indicate that the method is receiving a string that will be used inside another ComplexType. It returns arrays of ComplexTypes instead of a single cohesive one. Consumers should not need to use this parameter; it should only be used internally.
@param *strings [Array<String>] The type definitions to parse @param partial [Boolean] True if the string is part of a another type @return [ComplexType, Array, nil]
# File lib/solargraph/complex_type.rb, line 158 def parse *strings, partial: false @cache ||= {} unless partial cached = @cache[strings] return cached unless cached.nil? end types = [] key_types = nil strings.each do |type_string| point_stack = 0 curly_stack = 0 paren_stack = 0 base = String.new subtype_string = String.new type_string&.each_char do |char| if char == '=' #raise ComplexTypeError, "Invalid = in type #{type_string}" unless curly_stack > 0 elsif char == '<' point_stack += 1 elsif char == '>' if subtype_string.end_with?('=') && curly_stack > 0 subtype_string += char elsif base.end_with?('=') raise ComplexTypeError, "Invalid hash thing" unless key_types.nil? # types.push ComplexType.new([UniqueType.new(base[0..-2].strip)]) types.push UniqueType.new(base[0..-2].strip) key_types = types types = [] base.clear subtype_string.clear next else raise ComplexTypeError, "Invalid close in type #{type_string}" if point_stack == 0 point_stack -= 1 subtype_string += char end next elsif char == '{' curly_stack += 1 elsif char == '}' curly_stack -= 1 subtype_string += char raise ComplexTypeError, "Invalid close in type #{type_string}" if curly_stack < 0 next elsif char == '(' paren_stack += 1 elsif char == ')' paren_stack -= 1 subtype_string += char if paren_stack == 0 raise ComplexTypeError, "Invalid close in type #{type_string}" if paren_stack < 0 next elsif char == ',' && point_stack == 0 && curly_stack == 0 && paren_stack == 0 # types.push ComplexType.new([UniqueType.new(base.strip, subtype_string.strip)]) types.push UniqueType.new(base.strip, subtype_string.strip) base.clear subtype_string.clear next end if point_stack == 0 && curly_stack == 0 && paren_stack == 0 base.concat char else subtype_string.concat char end end raise ComplexTypeError, "Unclosed subtype in #{type_string}" if point_stack != 0 || curly_stack != 0 || paren_stack != 0 # types.push ComplexType.new([UniqueType.new(base, subtype_string)]) types.push UniqueType.new(base.strip, subtype_string.strip) end unless key_types.nil? raise ComplexTypeError, "Invalid use of key/value parameters" unless partial return key_types if types.empty? return [key_types, types] end result = partial ? types : ComplexType.new(types) @cache[strings] = result unless partial result end
try_parse(*strings)
click to toggle source
@param strings [Array<String>] @return [ComplexType]
# File lib/solargraph/complex_type.rb, line 238 def try_parse *strings parse *strings rescue ComplexTypeError => e Solargraph.logger.info "Error parsing complex type: #{e.message}" ComplexType::UNDEFINED end
Public Instance Methods
[](index)
click to toggle source
# File lib/solargraph/complex_type.rb, line 63 def [](index) @items[index] end
all?(&block)
click to toggle source
# File lib/solargraph/complex_type.rb, line 89 def all? &block @items.all? &block end
all_params()
click to toggle source
# File lib/solargraph/complex_type.rb, line 123 def all_params @items.first.all_params || [] end
any?(&block)
click to toggle source
# File lib/solargraph/complex_type.rb, line 93 def any? &block @items.compact.any? &block end
each(&block)
click to toggle source
@yieldparam [UniqueType] @return [Array]
# File lib/solargraph/complex_type.rb, line 45 def each &block @items.each &block end
each_unique_type(&block)
click to toggle source
@yieldparam [UniqueType] @return [Enumerator<UniqueType>]
# File lib/solargraph/complex_type.rb, line 51 def each_unique_type &block return enum_for(__method__) unless block_given? @items.each do |item| item.each_unique_type &block end end
first()
click to toggle source
# File lib/solargraph/complex_type.rb, line 29 def first @items.first end
length()
click to toggle source
# File lib/solargraph/complex_type.rb, line 59 def length @items.length end
map(&block)
click to toggle source
# File lib/solargraph/complex_type.rb, line 39 def map &block @items.map &block end
method_missing(name, *args, &block)
click to toggle source
Calls superclass method
# File lib/solargraph/complex_type.rb, line 75 def method_missing name, *args, &block return if @items.first.nil? return @items.first.send(name, *args, &block) if respond_to_missing?(name) super end
namespace()
click to toggle source
# File lib/solargraph/complex_type.rb, line 70 def namespace # cache this attr for high frequency call @namespace ||= method_missing(:namespace).to_s end
nullable?()
click to toggle source
# File lib/solargraph/complex_type.rb, line 119 def nullable? @items.any?(&:nil_type?) end
parameterized?()
click to toggle source
# File lib/solargraph/complex_type.rb, line 101 def parameterized? any?(&:parameterized?) end
qualify(api_map, context = '')
click to toggle source
@param api_map [ApiMap] @param context [String] @return [ComplexType]
# File lib/solargraph/complex_type.rb, line 21 def qualify api_map, context = '' types = @items.map do |t| next t if ['Boolean', 'nil', 'void', 'undefined'].include?(t.name) t.qualify api_map, context end ComplexType.new(types) end
resolve_parameters(definitions, context)
click to toggle source
# File lib/solargraph/complex_type.rb, line 105 def resolve_parameters definitions, context result = @items.map { |i| i.resolve_parameters(definitions, context) } ComplexType.parse(*result.map(&:tag)) end
respond_to_missing?(name, include_private = false)
click to toggle source
Calls superclass method
# File lib/solargraph/complex_type.rb, line 81 def respond_to_missing?(name, include_private = false) TypeMethods.public_instance_methods.include?(name) || super end
select(&block)
click to toggle source
# File lib/solargraph/complex_type.rb, line 67 def select &block @items.select &block end
self_to(dst)
click to toggle source
@param dst [String] @return [ComplexType]
# File lib/solargraph/complex_type.rb, line 112 def self_to dst return self unless selfy? red = reduce_class(dst) result = @items.map { |i| i.self_to red } ComplexType.parse(*result.map(&:to_s)) end
selfy?()
click to toggle source
# File lib/solargraph/complex_type.rb, line 97 def selfy? @items.any?(&:selfy?) end
to_rbs()
click to toggle source
# File lib/solargraph/complex_type.rb, line 33 def to_rbs ((@items.length > 1 ? '(' : '') + @items.map do |item| "#{item.namespace}#{item.parameters? ? "[#{item.subtypes.map { |s| s.to_rbs }.join(', ')}]" : ''}" end.join(' | ') + (@items.length > 1 ? ')' : '')).gsub(/undefined/, 'untyped') end
to_s()
click to toggle source
# File lib/solargraph/complex_type.rb, line 85 def to_s map(&:tag).join(', ') end
Private Instance Methods
reduce_class(dst)
click to toggle source
@todo This is a quick and dirty hack that forces `self` keywords
to reference an instance of their class and never the class itself. This behavior may change depending on which result is expected from YARD conventions. See https://github.com/lsegal/yard/issues/1257
@param dst [String] @return [String]
# File lib/solargraph/complex_type.rb, line 135 def reduce_class dst while dst =~ /^(Class|Module)\<(.*?)\>$/ dst = dst.sub(/^(Class|Module)\</, '').sub(/\>$/, '') end dst end