Class: Steep::Subtyping::VariableVariance

Inherits:
Object
  • Object
show all
Defined in:
lib/steep/subtyping/variable_variance.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(covariants:, contravariants:) ⇒ VariableVariance

Returns a new instance of VariableVariance.



7
8
9
10
# File 'lib/steep/subtyping/variable_variance.rb', line 7

def initialize(covariants:, contravariants:)
  @covariants = covariants
  @contravariants = contravariants
end

Instance Attribute Details

#contravariantsObject (readonly)

Returns the value of attribute contravariants.



5
6
7
# File 'lib/steep/subtyping/variable_variance.rb', line 5

def contravariants
  @contravariants
end

#covariantsObject (readonly)

Returns the value of attribute covariants.



4
5
6
# File 'lib/steep/subtyping/variable_variance.rb', line 4

def covariants
  @covariants
end

Class Method Details

.add_params(params, block:, covariants:, contravariants:) ⇒ Object



39
40
41
42
43
# File 'lib/steep/subtyping/variable_variance.rb', line 39

def self.add_params(params, block:, covariants:, contravariants:)
  params.each_type do |type|
    add_type(type, variance: block ? :contravariant : :covariant, covariants: covariants, contravariants: contravariants)
  end
end

.add_type(type, variance:, covariants:, contravariants:) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/steep/subtyping/variable_variance.rb', line 45

def self.add_type(type, variance:, covariants:, contravariants:)
  case type
  when AST::Types::Var
    case variance
    when :covariant
      covariants << type.name
    when :contravariant
      contravariants << type.name
    when :invariant
      covariants << type.name
      contravariants << type.name
    end
  when AST::Types::Union, AST::Types::Intersection, AST::Types::Tuple
    type.types.each do |ty|
      add_type(ty, variance: variance, covariants: covariants, contravariants: contravariants)
    end
  when AST::Types::Name::Interface, AST::Types::Name::Instance, AST::Types::Name::Alias
    type.args.each do |arg|
      add_type(arg, variance: :invariant, covariants: covariants, contravariants: contravariants)
    end
  end
end

.from_method_type(method_type) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/steep/subtyping/variable_variance.rb', line 24

def self.from_method_type(method_type)
  covariants = Set.new
  contravariants = Set.new

  add_params(method_type.params, block: false, contravariants: contravariants, covariants: covariants)
  add_type(method_type.return_type, variance: :covariant, covariants: covariants, contravariants: contravariants)

  method_type.block&.type&.yield_self do |proc|
    add_params(proc.params, block: true, contravariants: contravariants, covariants: covariants)
    add_type(proc.return_type, variance: :contravariant, covariants: covariants, contravariants: contravariants)
  end

  new(covariants: covariants, contravariants: contravariants)
end

Instance Method Details

#contravariant?(var) ⇒ Boolean

Returns:

  • (Boolean)


16
17
18
# File 'lib/steep/subtyping/variable_variance.rb', line 16

def contravariant?(var)
  contravariants.member?(var) && !covariants.member?(var)
end

#covariant?(var) ⇒ Boolean

Returns:

  • (Boolean)


12
13
14
# File 'lib/steep/subtyping/variable_variance.rb', line 12

def covariant?(var)
  covariants.member?(var) && !contravariants.member?(var)
end

#invariant?(var) ⇒ Boolean

Returns:

  • (Boolean)


20
21
22
# File 'lib/steep/subtyping/variable_variance.rb', line 20

def invariant?(var)
  covariants.member?(var) && contravariants.member?(var)
end