Class: Solargraph::ComplexType::UniqueType

Inherits:
Object
  • Object
show all
Includes:
TypeMethods, Equality, Logging
Defined in:
lib/solargraph/complex_type/unique_type.rb

Overview

An individual type signature. A complex type can consist of multiple unique types.

Constant Summary collapse

UNDEFINED =
UniqueType.new('undefined', rooted: false)
BOOLEAN =
UniqueType.new('Boolean', rooted: true)
TRUE =
UniqueType.new('true', rooted: true)
FALSE =
UniqueType.new('false', rooted: true)
NIL =
UniqueType.new('nil', rooted: true)
SINGLE_SUBTYPE =
{
  '::TrueClass' => UniqueType::TRUE,
  '::FalseClass' => UniqueType::FALSE,
  '::NilClass' => UniqueType::NIL
}.freeze

Constants included from Logging

Logging::DEFAULT_LOG_LEVEL, Logging::LOG_LEVELS

Constants included from TypeMethods

TypeMethods::PARAMETERS_TYPE_BY_STARTING_TAG

Instance Attribute Summary collapse

Attributes included from TypeMethods

#name, #parameters_type

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Logging

log_level, logger

Methods included from Equality

#freeze

Methods included from TypeMethods

#defined?, #duck_type?, #each_unique_type, #erase_generics, #erased_variance, #fixed_parameters?, #generate_substring_from, #hash_parameters?, #list_parameters?, #namespace, #namespace_type, #nil_type?, #rooted_name, #rooted_namespace, #rooted_substring, #rooted_tag, #scope, #substring, #tag, #tuple?, #undefined?, #value_types, #void?

Constructor Details

#initialize(name, key_types = [], subtypes = [], rooted:, parameters_type: nil) ⇒ UniqueType

Returns a new instance of UniqueType.

Parameters:

  • name (String)
  • key_types (Array<ComplexType>) (defaults to: [])
  • subtypes (Array<ComplexType>) (defaults to: [])
  • rooted (Boolean)
  • parameters_type (Symbol, nil) (defaults to: nil)


72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/solargraph/complex_type/unique_type.rb', line 72

def initialize name, key_types = [], subtypes = [], rooted:, parameters_type: nil
  if parameters_type.nil? && !(key_types.empty? && subtypes.empty?)
    raise 'You must supply parameters_type if you provide parameters'
  end
  raise "Please remove leading :: and set rooted instead - #{name.inspect}" if name.start_with?('::')
  @name = name
  @parameters_type = parameters_type
  if implicit_union?
    @key_types = key_types.uniq
    @subtypes = subtypes.uniq
  else
    @key_types = key_types
    @subtypes = subtypes
  end
  @rooted = rooted
  @all_params = []
  @all_params.concat @key_types
  @all_params.concat @subtypes
end

Instance Attribute Details

#all_paramsObject (readonly)

Returns the value of attribute all_params.



12
13
14
# File 'lib/solargraph/complex_type/unique_type.rb', line 12

def all_params
  @all_params
end

#key_typesObject (readonly)

Returns the value of attribute key_types.



12
13
14
# File 'lib/solargraph/complex_type/unique_type.rb', line 12

def key_types
  @key_types
end

#subtypesObject (readonly)

Returns the value of attribute subtypes.



12
13
14
# File 'lib/solargraph/complex_type/unique_type.rb', line 12

def subtypes
  @subtypes
end

Class Method Details

.can_root_name?(name) ⇒ Boolean

Parameters:

  • name (String)

Returns:

  • (Boolean)


614
615
616
617
# File 'lib/solargraph/complex_type/unique_type.rb', line 614

def self.can_root_name? name
  # name is not lowercase
  !name.empty? && name != name.downcase
end

.parse(name, substring = '', make_rooted: nil) ⇒ UniqueType

Create a UniqueType with the specified name and an optional substring. The substring is the parameter section of a parametrized type, e.g., for the type ‘Array<String>`, the name is `Array` and the substring is `<String>`.

Parameters:

  • name (String)

    The name of the type

  • substring (String) (defaults to: '')

    The substring of the type

  • make_rooted (Boolean, nil) (defaults to: nil)

Returns:

Raises:



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/solargraph/complex_type/unique_type.rb', line 23

def self.parse name, substring = '', make_rooted: nil
  raise ComplexTypeError, "Illegal prefix: #{name}" if name.start_with?(':::')
  if name.start_with?('::')
    name = name[2..]
    rooted = true
  elsif !can_root_name?(name)
    rooted = true
  else
    rooted = false
  end
  rooted = make_rooted unless make_rooted.nil?

  # @type [Array<ComplexType>]
  key_types = []
  # @type [Array<ComplexType>]
  subtypes = []
  parameters_type = nil
  unless substring.empty?
    subs = ComplexType.parse(substring[1..-2], partial: true)
    # @sg-ignore Need to add nil check here
    parameters_type = PARAMETERS_TYPE_BY_STARTING_TAG.fetch(substring[0])
    if parameters_type == :hash
      unless !subs.is_a?(ComplexType) && (subs.length == 2) && !subs[0].is_a?(UniqueType) && !subs[1].is_a?(UniqueType)
        raise ComplexTypeError,
              "Bad hash type: name=#{name}, substring=#{substring}"
      end
      key_types.concat(subs[0].map { |u| ComplexType.new([u]) })
      subtypes.concat(subs[1].map { |u| ComplexType.new([u]) })
    elsif parameters_type == :list && name == 'Hash'
      # Treat Hash<A, B> as Hash{A => B}
      if subs.length != 2
        raise ComplexTypeError,
              "Bad hash type: name=#{name}, substring=#{substring} - must have exactly two parameters"
      end
      key_types.concat(subs[0].map { |u| ComplexType.new([u]) })
      subtypes.concat(subs[1].map { |u| ComplexType.new([u]) })
    else
      subtypes.concat subs
    end
  end
  # @sg-ignore Need to add nil check here
  new(name, key_types, subtypes, rooted: rooted, parameters_type: parameters_type)
end

Instance Method Details

#==(other) ⇒ Object



200
201
202
# File 'lib/solargraph/complex_type/unique_type.rb', line 200

def == other
  eql?(other)
end

#all?(&block) ⇒ Boolean

Yield Returns:

  • (Boolean)

Returns:

  • (Boolean)


372
373
374
# File 'lib/solargraph/complex_type/unique_type.rb', line 372

def all? &block
  block.yield self
end

#all_rooted?Boolean

Returns:

  • (Boolean)


599
600
601
602
# File 'lib/solargraph/complex_type/unique_type.rb', line 599

def all_rooted?
  return true if name == GENERIC_TAG_NAME
  rooted? && all_params.all?(&:rooted?)
end

#any?(&block) ⇒ Boolean

Yield Returns:

  • (Boolean)

Returns:

  • (Boolean)


584
585
586
# File 'lib/solargraph/complex_type/unique_type.rb', line 584

def any? &block
  block.yield self
end

#can_root_name?(name_to_check = name) ⇒ Boolean

Parameters:

  • name_to_check (String) (defaults to: name)

Returns:

  • (Boolean)


609
610
611
# File 'lib/solargraph/complex_type/unique_type.rb', line 609

def can_root_name? name_to_check = name
  self.class.can_root_name?(name_to_check)
end

#conforms_to?(api_map, expected, situation, rules = [], variance: erased_variance(situation)) ⇒ Boolean

Parameters:

  • api_map (ApiMap)
  • expected (ComplexType::UniqueType, ComplexType)
  • situation (:method_call, :assignment, :return_type)
  • rules (Array<:allow_subtype_skew, :allow_empty_params, :allow_reverse_match, :allow_any_match, :allow_undefined, :allow_unresolved_generic>) (defaults to: [])
  • variance (:invariant, :covariant, :contravariant) (defaults to: erased_variance(situation))

Returns:

  • (Boolean)


254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
# File 'lib/solargraph/complex_type/unique_type.rb', line 254

def conforms_to? api_map, expected, situation, rules = [],
                 variance: erased_variance(situation)
  return true if undefined? && rules.include?(:allow_undefined)

  # @todo teach this to validate duck types as inferred type
  return true if duck_type?

  # complex types as expectations are unions - we only need to
  # match one of their unique types
  expected.any? do |expected_unique_type|
    # :nocov:
    unless expected_unique_type.instance_of?(UniqueType)
      raise "Expected type must be a UniqueType, got #{expected_unique_type.class} in #{expected.inspect}"
    end
    # :nocov:
    conformance = Conformance.new(api_map, self, expected_unique_type, situation,
                                  rules, variance: variance)
    conformance.conforms_to_unique_type?
  end
end

#descString

Returns:

  • (String)


301
302
303
# File 'lib/solargraph/complex_type/unique_type.rb', line 301

def desc
  rooted_tags
end

#determine_non_literal_nameString

Returns:

  • (String)


167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/solargraph/complex_type/unique_type.rb', line 167

def determine_non_literal_name
  # https://github.com/ruby/rbs/blob/master/docs/syntax.md
  #
  # _literal_ ::= _string-literal_
  #    | _symbol-literal_
  #    | _integer-literal_
  #    | `true`
  #    | `false`
  return name if name.empty?
  return 'NilClass' if name == 'nil'
  return 'Boolean' if %w[true false].include?(name)
  return 'Symbol' if name[0] == ':'
  return 'String' if ['"', "'"].include?(name[0])
  return 'Integer' if name.match?(/^-?\d+$/)
  name
end

#downcast_to_literal_if_possibleUniqueType

Returns:



377
378
379
380
# File 'lib/solargraph/complex_type/unique_type.rb', line 377

def downcast_to_literal_if_possible
  return self
  SINGLE_SUBTYPE.fetch(rooted_tag, self)
end

#each {|t| ... } ⇒ Enumerable<self>

Yield Parameters:

  • t (self)

Yield Returns:

  • (self)

Returns:

  • (Enumerable<self>)


484
485
486
# File 'lib/solargraph/complex_type/unique_type.rb', line 484

def each(&)
  [self].each(&)
end

#eql?(other) ⇒ Boolean

Returns:

  • (Boolean)


184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/solargraph/complex_type/unique_type.rb', line 184

def eql? other
  self.class == other.class &&
    # @sg-ignore flow sensitive typing should support .class == .class
    @name == other.name &&
    # @sg-ignore flow sensitive typing should support .class == .class
    @key_types == other.key_types &&
    # @sg-ignore flow sensitive typing should support .class == .class
    @subtypes == other.subtypes &&
    # @sg-ignore flow sensitive typing should support .class == .class
    @rooted == other.rooted? &&
    # @sg-ignore flow sensitive typing should support .class == .class
    @all_params == other.all_params &&
    # @sg-ignore flow sensitive typing should support .class == .class
    @parameters_type == other.parameters_type
end

#erase_parametersself

Returns:

  • (self)


280
281
282
# File 'lib/solargraph/complex_type/unique_type.rb', line 280

def erase_parameters
  UniqueType.new(name, rooted: rooted?, parameters_type: parameters_type)
end

#erased_version_of?(other) ⇒ Boolean

Parameters:

Returns:

  • (Boolean)


245
246
247
# File 'lib/solargraph/complex_type/unique_type.rb', line 245

def erased_version_of? other
  name == other.name && (all_params.empty? || all_params.all?(&:undefined?))
end

#exclude(exclude_types, api_map) ⇒ ComplexType, self

Parameters:

Returns:



114
115
116
117
118
119
120
# File 'lib/solargraph/complex_type/unique_type.rb', line 114

def exclude exclude_types, api_map
  return self if exclude_types.nil?

  types = items - exclude_types.items
  types = [ComplexType::UniqueType::UNDEFINED] if types.empty?
  ComplexType.new(types)
end

#force_rootedself

Returns:

  • (self)


521
522
523
524
525
# File 'lib/solargraph/complex_type/unique_type.rb', line 521

def force_rooted
  transform do |t|
    t.recreate(make_rooted: true)
  end
end

#generic?Boolean

Returns:

  • (Boolean)


363
364
365
# File 'lib/solargraph/complex_type/unique_type.rb', line 363

def generic?
  name == GENERIC_TAG_NAME || all_params.any?(&:generic?)
end

#hashObject



275
276
277
# File 'lib/solargraph/complex_type/unique_type.rb', line 275

def hash
  [self.class, @name, @key_types, @sub_types, @rooted, @all_params, @parameters_type].hash
end

#implicit_union?Boolean

Returns:

  • (Boolean)


92
93
94
95
96
97
# File 'lib/solargraph/complex_type/unique_type.rb', line 92

def implicit_union?
  # @todo use api_map to establish number of generics in type;
  #   if only one is allowed but multiple are passed in, treat
  #   those as implicit unions
  %w[Hash Array Set _ToAry Enumerable _Each].include?(name) && parameters_type != :fixed
end

#interface?Boolean

Whether this is an RBS interface like _ToAry or Hash::_Key.

Returns:

  • (Boolean)


240
241
242
# File 'lib/solargraph/complex_type/unique_type.rb', line 240

def interface?
  name.start_with?('_') || name.include?('::_')
end

#intersect_with(intersection_type, api_map) ⇒ self, ComplexType

Parameters:

Returns:

See Also:



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/solargraph/complex_type/unique_type.rb', line 127

def intersect_with intersection_type, api_map
  return self if intersection_type.nil?
  return intersection_type if undefined?
  types = []
  # try to find common types via conformance
  items.each do |ut|
    intersection_type.each do |int_type|
      if ut.conforms_to?(api_map, int_type, :assignment)
        types << ut
      elsif int_type.conforms_to?(api_map, ut, :assignment)
        types << int_type
      end
    end
  end
  types = [ComplexType::UniqueType::UNDEFINED] if types.empty?
  ComplexType.new(types)
end

#itemsArray<UniqueType>

Returns:



285
286
287
# File 'lib/solargraph/complex_type/unique_type.rb', line 285

def items
  [self]
end

#literal?Boolean

Returns:

  • (Boolean)


149
150
151
152
# File 'lib/solargraph/complex_type/unique_type.rb', line 149

def literal?
  return false
  non_literal_name != name
end

#map {|t| ... } ⇒ Array<self>

Yield Parameters:

  • t (self)

Yield Returns:

  • (self)

Returns:

  • (Array<self>)


477
478
479
# File 'lib/solargraph/complex_type/unique_type.rb', line 477

def map &block
  [block.yield(self)]
end

#non_literal_nameString

Returns:

  • (String)


155
156
157
# File 'lib/solargraph/complex_type/unique_type.rb', line 155

def non_literal_name
  @non_literal_name ||= determine_non_literal_name
end

#nullable?Boolean

Returns:

  • (Boolean)


367
368
369
# File 'lib/solargraph/complex_type/unique_type.rb', line 367

def nullable?
  nil_type?
end

#parameter_variance(_situation, default = :covariant) ⇒ :invariant, ...

“[Expected] type variables that are COVARIANT can be substituted with

a more specific [inferred] type without causing errors"

“[Expected] type variables that are CONTRAVARIANT can be substituted

with a more general [inferred] type without causing errors"

“[Expected] types where neither is possible are INVARIANT”

Parameters:

  • _situation (:method_call, :return_type)
  • default (Symbol) (defaults to: :covariant)

    The default variance to return if the type is not one of the special cases

Returns:

  • (:invariant, :covariant, :contravariant)


218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
# File 'lib/solargraph/complex_type/unique_type.rb', line 218

def parameter_variance _situation, default = :covariant
  # @todo RBS can specify variance - maybe we can use that info
  #   and also let folks specify?
  #
  # Array/Set: ideally invariant, since we don't know if user is
  #   going to add new stuff into it or read it.  But we don't
  #   have a way to specify, so we use covariant
  # Enumerable: covariant:  can't be changed, so we can pass
  #   in more specific subtypes
  # Hash: read-only would be covariant, read-write would be
  #   invariant if we could distinguish that - should default to
  #   covariant
  # contravariant?: Proc - can be changed, so we can pass
  #   in less specific super types
  # if %w[Hash Tuple Array Set Enumerable].include?(name) && fixed_parameters?
  #   :covariant
  # else
  default
  # end
end

#parameters?Boolean

Returns:

  • (Boolean)


337
338
339
# File 'lib/solargraph/complex_type/unique_type.rb', line 337

def parameters?
  !all_params.empty?
end

#parameters_as_rbsString

Returns:

  • (String)


352
353
354
355
356
357
358
359
360
361
# File 'lib/solargraph/complex_type/unique_type.rb', line 352

def parameters_as_rbs
  return '' unless parameters?

  return "[#{all_params.map(&:to_rbs).join(', ')}]" if key_types.empty?

  # handle, e.g., Hash[K, V] case
  key_types_str = rbs_union(key_types)
  subtypes_str = rbs_union(subtypes)
  "[#{key_types_str}, #{subtypes_str}]"
end

#qualify(api_map, *gates) ⇒ self, ...

Generate a ComplexType that fully qualifies this type’s namespaces.

Parameters:

  • api_map (ApiMap)

    The ApiMap that performs qualification

  • gates (Array<String>)

    The namespaces from which to resolve names

Returns:



555
556
557
558
559
560
561
562
563
564
565
566
567
# File 'lib/solargraph/complex_type/unique_type.rb', line 555

def qualify api_map, *gates
  transform do |t|
    next t if t.name == GENERIC_TAG_NAME
    next t if t.duck_type? || t.void? || t.undefined? || t.literal?
    open = t.rooted? ? [''] : gates
    fqns = api_map.qualify(t.non_literal_name, *open)
    if fqns.nil?
      next UniqueType::BOOLEAN if t.tag == 'Boolean'
      next UniqueType::UNDEFINED
    end
    t.recreate(new_name: fqns, make_rooted: true)
  end
end

#rbs_nameString

Returns:

  • (String)


290
291
292
293
294
295
296
297
298
# File 'lib/solargraph/complex_type/unique_type.rb', line 290

def rbs_name
  if name == 'undefined'
    'untyped'
  elsif literal?
    name
  else
    rooted_name
  end
end

#rbs_union(types) ⇒ String

Parameters:

Returns:

  • (String)


343
344
345
346
347
348
349
# File 'lib/solargraph/complex_type/unique_type.rb', line 343

def rbs_union types
  if types.length == 1
    types.first.to_rbs
  else
    "(#{types.map(&:to_rbs).join(' | ')})"
  end
end

#recreate(new_name: nil, make_rooted: nil, new_key_types: nil, new_subtypes: nil) ⇒ self

Parameters:

  • new_name (String, nil) (defaults to: nil)
  • make_rooted (Boolean, nil) (defaults to: nil)
  • new_key_types (Array<ComplexType>, nil) (defaults to: nil)
  • make_rooted (Boolean, nil) (defaults to: nil)
  • new_subtypes (Array<ComplexType>, nil) (defaults to: nil)

Returns:

  • (self)


499
500
501
502
503
504
505
506
507
508
# File 'lib/solargraph/complex_type/unique_type.rb', line 499

def recreate new_name: nil, make_rooted: nil, new_key_types: nil, new_subtypes: nil
  raise "Please remove leading :: and set rooted instead - #{new_name}" if new_name&.start_with?('::')

  new_name ||= name
  new_key_types ||= @key_types
  new_subtypes ||= @subtypes
  make_rooted = @rooted if make_rooted.nil?
  # @sg-ignore flow sensitive typing needs better handling of ||= on lvars
  UniqueType.new(new_name, new_key_types, new_subtypes, rooted: make_rooted, parameters_type: parameters_type)
end

#reduce_class_typeComplexType

Returns:



589
590
591
592
593
594
595
596
597
# File 'lib/solargraph/complex_type/unique_type.rb', line 589

def reduce_class_type
  new_items = items.flat_map do |type|
    next type unless %w[Module Class].include?(type.name)
    next type if type.all_params.empty?

    type.all_params
  end
  ComplexType.new(new_items)
end

#resolve_generics(definitions, context_type) ⇒ UniqueType, ComplexType

Probe the concrete type for each of the generic type parameters used in this type, and return a new type if possible.

Parameters:

Returns:



445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
# File 'lib/solargraph/complex_type/unique_type.rb', line 445

def resolve_generics definitions, context_type
  return self if definitions.nil? || definitions.generics.empty?

  transform(name) do |t|
    if t.name == GENERIC_TAG_NAME
      generic_name = t.subtypes.first&.name
      idx = definitions.generics.index(generic_name)
      next t if idx.nil?
      if context_type.parameters_type == :hash
        if idx.zero?
          next ComplexType.new(context_type.key_types)
        elsif idx == 1
          next ComplexType.new(context_type.subtypes)
        else
          next ComplexType::UNDEFINED
        end
      # @todo Treating parameterized classes and tuples the same for now
      # elsif context_type.all?(&:implicit_union?) || true
      elsif idx.zero? && !context_type.all_params.empty?
        ComplexType.new(context_type.all_params)
      else
        ComplexType::UNDEFINED
      end
    else
      t
    end
  end
end

#resolve_generics_from_context(generics_to_resolve, context_type, resolved_generic_values: {}) ⇒ UniqueType, ComplexType

Parameters:

Returns:



386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
# File 'lib/solargraph/complex_type/unique_type.rb', line 386

def resolve_generics_from_context generics_to_resolve, context_type, resolved_generic_values: {}
  if name == ComplexType::GENERIC_TAG_NAME
    type_param = subtypes.first&.name
    return self unless generics_to_resolve.include? type_param
    # @sg-ignore flow sensitive typing needs to eliminate literal from union with [:bar].include?(foo)
    unless context_type.nil? || !resolved_generic_values[type_param].nil?
      new_binding = true
      # @sg-ignore flow sensitive typing needs to eliminate literal from union with [:bar].include?(foo)
      resolved_generic_values[type_param] = context_type
    end
    if new_binding
      resolved_generic_values.transform_values! do |complex_type|
        complex_type.resolve_generics_from_context(generics_to_resolve, nil,
                                                   resolved_generic_values: resolved_generic_values)
      end
    end
    # @sg-ignore flow sensitive typing needs to eliminate literal from union with [:bar].include?(foo)
    return resolved_generic_values[type_param] || self
  end

  # @todo typechecking should complain when the method being called has no @yieldparam tag
  new_key_types = resolve_param_generics_from_context(generics_to_resolve, context_type, resolved_generic_values,
                                                      &:key_types)
  new_subtypes = resolve_param_generics_from_context(generics_to_resolve, context_type, resolved_generic_values,
                                                     &:subtypes)
  recreate(new_key_types: new_key_types, new_subtypes: new_subtypes)
end

#resolve_param_generics_from_context(generics_to_resolve, context_type, resolved_generic_values) ⇒ Array<ComplexType>

Parameters:

Yield Returns:

Returns:



419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
# File 'lib/solargraph/complex_type/unique_type.rb', line 419

def resolve_param_generics_from_context generics_to_resolve, context_type, resolved_generic_values
  types = yield self
  types.each_with_index.flat_map do |ct, i|
    ct.items.flat_map do |ut|
      context_params = yield context_type if context_type
      if context_params && context_params[i]
        type_arg = context_params[i]
        type_arg.map do |new_unique_context_type|
          ut.resolve_generics_from_context generics_to_resolve, new_unique_context_type,
                                           resolved_generic_values: resolved_generic_values
        end
      else
        ut.resolve_generics_from_context generics_to_resolve, nil,
                                         resolved_generic_values: resolved_generic_values
      end
    end
  end
end

#rooted?Boolean

Returns:

  • (Boolean)


604
605
606
# File 'lib/solargraph/complex_type/unique_type.rb', line 604

def rooted?
  !can_root_name? || @rooted
end

#rooted_tagsString

Returns:

  • (String)


511
512
513
# File 'lib/solargraph/complex_type/unique_type.rb', line 511

def rooted_tags
  rooted_tag
end

#self_to_type(dst) ⇒ self

Parameters:

Returns:

  • (self)


575
576
577
578
579
580
581
# File 'lib/solargraph/complex_type/unique_type.rb', line 575

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

#selfy?Boolean

Returns:

  • (Boolean)


569
570
571
# File 'lib/solargraph/complex_type/unique_type.rb', line 569

def selfy?
  @name == 'self' || @key_types.any?(&:selfy?) || @subtypes.any?(&:selfy?)
end

#simplify_literalsself

Returns:

  • (self)


104
105
106
107
108
109
# File 'lib/solargraph/complex_type/unique_type.rb', line 104

def simplify_literals
  transform do |t|
    next t unless t.literal?
    t.recreate(new_name: t.non_literal_name)
  end
end

#simplifyable_literal?Boolean

Returns:

  • (Boolean)


145
146
147
# File 'lib/solargraph/complex_type/unique_type.rb', line 145

def simplifyable_literal?
  literal? && name != 'nil'
end

#tagsString

Returns:

  • (String)


516
517
518
# File 'lib/solargraph/complex_type/unique_type.rb', line 516

def tags
  tag
end

#to_aArray<UniqueType>

Returns:



489
490
491
# File 'lib/solargraph/complex_type/unique_type.rb', line 489

def to_a
  [self]
end

#to_rbsString

@sg-ignore Need better if/elseanalysis

Returns:

  • (String)


307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
# File 'lib/solargraph/complex_type/unique_type.rb', line 307

def to_rbs
  if duck_type?
    'untyped'
  elsif name == 'Boolean'
    'bool'
  elsif name.downcase == 'nil'
    'nil'
  elsif name == GENERIC_TAG_NAME
    all_params.first&.name
  elsif %w[Class Module].include?(name)
    rbs_name
  elsif %w[Tuple Array].include?(name) && fixed_parameters?
    # tuples don't have a name; they're just [foo, bar, baz].
    if substring == '()'
      # but there are no zero element tuples, so we go with an array
      if rooted?
        '::Array[]'
      else
        'Array[]'
      end
    else
      # already generated surrounded by []
      parameters_as_rbs
    end
  else
    "#{rbs_name}#{parameters_as_rbs}"
  end
end

#to_sObject



99
100
101
# File 'lib/solargraph/complex_type/unique_type.rb', line 99

def to_s
  tag
end

#transform(new_name = nil) {|t| ... } ⇒ self

Apply the given transformation to each subtype and then finally to this type

Parameters:

  • new_name (String, nil) (defaults to: nil)

Yield Parameters:

Yield Returns:

  • (self)

Returns:

  • (self)


533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
# File 'lib/solargraph/complex_type/unique_type.rb', line 533

def transform new_name = nil, &transform_type
  if new_name&.start_with?('::')
    raise "Please remove leading :: and set rooted with recreate() instead - #{new_name}"
  end
  if name == ComplexType::GENERIC_TAG_NAME
    # doesn't make sense to manipulate the name of the generic
    new_key_types = @key_types
    new_subtypes = @subtypes
  else
    new_key_types = @key_types.flat_map { |ct| ct.items.map { |ut| ut.transform(&transform_type) } }
    new_subtypes = @subtypes.flat_map { |ct| ct.items.map { |ut| ut.transform(&transform_type) } }
  end
  new_type = recreate(new_name: new_name || name, new_key_types: new_key_types, new_subtypes: new_subtypes,
                      make_rooted: @rooted)
  yield new_type
end

#without_nilself

Returns:

  • (self)


160
161
162
163
164
# File 'lib/solargraph/complex_type/unique_type.rb', line 160

def without_nil
  return UniqueType::UNDEFINED if nil_type?

  self
end