class Solargraph::ComplexType
A container for type data based on YARD type tags.
def ==(other)
def ==(other) self.eql?(other) end
def [](index)
-
(UniqueType)-
Parameters:
-
index(Integer) --
def [](index) @items[index] end
def all? &block
def all? &block @items.all? &block end
def all_params
-
(Array-)
def all_params @items.first.all_params || [] end
def all_rooted?
every type and subtype in this union have been resolved to be
def all_rooted? all?(&:all_rooted?) end
def any? &block
def any? &block @items.compact.any? &block end
def bottom?
def bottom? @items.all?(&:bot?) end
def each &block
-
(Enumerable-)
Other tags:
- Yieldparam: -
def each &block @items.each &block end
def each_unique_type &block
-
(Enumerator-) -
(void)-
Overloads:
-
each_unique_type()
Other tags:
- Yieldparam: -
def each_unique_type &block return enum_for(__method__) unless block_given? @items.each do |item| item.each_unique_type &block end end
def eql?(other)
def eql?(other) self.class == other.class && @items == other.items end
def first
-
(UniqueType)-
def first @items.first end
def force_rooted
-
(self)-
def force_rooted transform do |t| t.recreate(make_rooted: true) end end
def generic?
def generic? any?(&:generic?) end
def hash
def hash [self.class, @items].hash end
def initialize types = [UniqueType::UNDEFINED]
-
types(Array) --
def initialize types = [UniqueType::UNDEFINED] # @todo @items here should not need an annotation # @type [Array<UniqueType>] @items = types.flat_map(&:items).uniq(&:to_s) end
def length
-
(Integer)-
def length @items.length end
def map &block
-
(Array)-
Other tags:
- Yieldparam: -
def map &block @items.map &block end
def method_missing name, *args, &block
-
(Object, nil)-
Parameters:
-
name(Symbol) --
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
def namespace
-
(String)-
def namespace # cache this attr for high frequency call @namespace ||= method_missing(:namespace).to_s end
def namespaces
-
(Array-)
def namespaces @items.map(&:namespace) end
def nullable?
def nullable? @items.any?(&:nil_type?) end
def parse *strings, partial: false
- Todo: - To be able to select the right signature above,
Returns:
-
(ComplexType)-
Parameters:
-
*strings(Array) -- The type definitions to parse
Other tags:
- Note: -
def parse *strings, partial: false # @type [Hash{Array<String> => ComplexType}] @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.parse(base[0..-2].strip, subtype_string) # @todo this should either expand key_type's type # automatically or complain about not being # compatible with key_type's type in type checking 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 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.parse(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.parse(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
def qualify api_map, context = ''
-
(ComplexType)-
Parameters:
-
context(String) -- -
api_map(ApiMap) --
def qualify api_map, context = '' red = reduce_object types = red.items.map do |t| next t if ['nil', 'void', 'undefined'].include?(t.name) next t if ['::Boolean'].include?(t.rooted_name) t.qualify api_map, context end ComplexType.new(types).reduce_object end
def reduce_class dst
-
(String)-
Parameters:
-
dst(String) --
Other tags:
- Todo: - This is a quick and dirty hack that forces `self` keywords
def reduce_class dst while dst =~ /^(Class|Module)\<(.*?)\>$/ dst = dst.sub(/^(Class|Module)\</, '').sub(/\>$/, '') end dst end
def reduce_class_type
-
(ComplexType)-
def reduce_class_type new_items = items.flat_map do |type| next type unless ['Module', 'Class'].include?(type.name) type.all_params end ComplexType.new(new_items) end
def reduce_object
-
(ComplexType)-
def reduce_object new_items = items.flat_map do |ut| next [ut] if ut.name != 'Object' || ut.subtypes.empty? ut.subtypes end ComplexType.new(new_items) end
def resolve_generics definitions, context_type
-
(ComplexType)-
Parameters:
-
context_type(ComplexType) -- -
definitions(Pin::Namespace, Pin::Method) --
def resolve_generics definitions, context_type result = @items.map { |i| i.resolve_generics(definitions, context_type) } ComplexType.new(result) end
def resolve_generics_from_context generics_to_resolve, context_type, resolved_generic_values: {}
-
(self)-
Parameters:
-
resolved_generic_values(Hash{String => ComplexType}) -- Added to as types are encountered or resolved -
context_type(UniqueType, nil) -- -
generics_to_resolve(Enumerable) -- ]
def resolve_generics_from_context generics_to_resolve, context_type, resolved_generic_values: {} return self unless generic? ComplexType.new(@items.map { |i| i.resolve_generics_from_context(generics_to_resolve, context_type, resolved_generic_values: resolved_generic_values) }) end
def respond_to_missing?(name, include_private = false)
-
include_private(Boolean) -- -
name(Symbol) --
def respond_to_missing?(name, include_private = false) TypeMethods.public_instance_methods.include?(name) || super end
def rooted?
every top-level type has resolved to be fully qualified; see
def rooted? all?(&:rooted?) end
def rooted?
def rooted? @items.all?(&:rooted?) end
def rooted_tags
def rooted_tags map(&:rooted_tag).join(', ') end
def select &block
-
(Array-)
def select &block @items.select &block end
def self_to_type dst
-
(ComplexType)-
Parameters:
-
dst(ComplexType) --
def self_to_type dst object_type_dst = dst.reduce_class_type transform do |t| next t if t.name != 'self' object_type_dst end end
def selfy?
def selfy? @items.any?(&:selfy?) end
def tags
def tags @items.map(&:tag).join(', ') end
def to_a
-
(Array-)
def to_a @items end
def to_rbs
-
(String)-
def to_rbs ((@items.length > 1 ? '(' : '') + @items.map(&:to_rbs).join(' | ') + (@items.length > 1 ? ')' : '')) end
def to_s
def to_s map(&:tag).join(', ') end
def transform(new_name = nil, &transform_type)
-
(ComplexType)-
Other tags:
- Yieldreturn: -
Other tags:
- Yieldparam: t -
Parameters:
-
new_name(String, nil) --
def transform(new_name = nil, &transform_type) raise "Please remove leading :: and set rooted with recreate() instead - #{new_name}" if new_name&.start_with?('::') ComplexType.new(map { |ut| ut.transform(new_name, &transform_type) }) end
def try_parse *strings
-
(ComplexType)-
Parameters:
-
strings(Array) --
def try_parse *strings parse *strings rescue ComplexTypeError => e Solargraph.logger.info "Error parsing complex type `#{strings.join(', ')}`: #{e.message}" ComplexType::UNDEFINED end