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)


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

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



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

def == other
  eql?(other)
end

#all?(&block) ⇒ Boolean

Yield Returns:

  • (Boolean)

Returns:

  • (Boolean)


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

def all? &block
  block.yield self
end

#all_rooted?Boolean

Returns:

  • (Boolean)


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

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

#any?(&block) ⇒ Boolean

Yield Returns:

  • (Boolean)

Returns:

  • (Boolean)


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

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)


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

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)


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

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)


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

def desc
  rooted_tags
end

#determine_non_literal_nameString

Returns:

  • (String)


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

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:



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

def downcast_to_literal_if_possible
  SINGLE_SUBTYPE.fetch(rooted_tag, self)
end

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

Yield Parameters:

  • t (self)

Yield Returns:

  • (self)

Returns:

  • (Enumerable<self>)


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

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

#eql?(other) ⇒ Boolean

Returns:

  • (Boolean)


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

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)


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

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

#erased_version_of?(other) ⇒ Boolean

Parameters:

Returns:

  • (Boolean)


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

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)


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

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

#generic?Boolean

Returns:

  • (Boolean)


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

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

#hashObject



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

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)


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

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:



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

def items
  [self]
end

#literal?Boolean

Returns:

  • (Boolean)


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

def literal?
  non_literal_name != name
end

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

Yield Parameters:

  • t (self)

Yield Returns:

  • (self)

Returns:

  • (Array<self>)


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

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

#non_literal_nameString

Returns:

  • (String)


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

def non_literal_name
  @non_literal_name ||= determine_non_literal_name
end

#nullable?Boolean

Returns:

  • (Boolean)


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

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)


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

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)


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

def parameters?
  !all_params.empty?
end

#parameters_as_rbsString

Returns:

  • (String)


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

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:



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

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)


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

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

#rbs_union(types) ⇒ String

Parameters:

Returns:

  • (String)


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

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)


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

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:



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

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:



443
444
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
473
# File 'lib/solargraph/complex_type/unique_type.rb', line 443

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
      elsif context_type.all?(&:implicit_union?)
        if idx.zero? && !context_type.all_params.empty?
          ComplexType.new(context_type.all_params)
        else
          ComplexType::UNDEFINED
        end
      else
        # @sg-ignore Need to add nil check here
        context_type.all_params[idx] || definitions.generic_defaults[generic_name] || ComplexType::UNDEFINED
      end
    else
      t
    end
  end
end

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

Parameters:

Returns:



384
385
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
# File 'lib/solargraph/complex_type/unique_type.rb', line 384

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:



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

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)


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

def rooted?
  !can_root_name? || @rooted
end

#rooted_tagsString

Returns:

  • (String)


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

def rooted_tags
  rooted_tag
end

#self_to_type(dst) ⇒ self

Parameters:

Returns:

  • (self)


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

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)


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

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)


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

def tags
  tag
end

#to_aArray<UniqueType>

Returns:



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

def to_a
  [self]
end

#to_rbsString

@sg-ignore Need better if/elseanalysis

Returns:

  • (String)


306
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
# File 'lib/solargraph/complex_type/unique_type.rb', line 306

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)


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

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)


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

def without_nil
  return UniqueType::UNDEFINED if nil_type?

  self
end