Class: Steep::Interface::Instantiated

Inherits:
Object
  • Object
show all
Defined in:
lib/steep/interface/instantiated.rb

Defined Under Namespace

Classes: InvalidIvarOverrideError, InvalidMethodOverrideError

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(type:, methods:, ivar_chains:) ⇒ Instantiated

Returns a new instance of Instantiated.



8
9
10
11
12
# File 'lib/steep/interface/instantiated.rb', line 8

def initialize(type:, methods:, ivar_chains:)
  @type = type
  @methods = methods
  @ivar_chains = ivar_chains
end

Instance Attribute Details

#ivar_chainsObject (readonly)

Returns the value of attribute ivar_chains.



6
7
8
# File 'lib/steep/interface/instantiated.rb', line 6

def ivar_chains
  @ivar_chains
end

#methodsObject (readonly)

Returns the value of attribute methods.



5
6
7
# File 'lib/steep/interface/instantiated.rb', line 5

def methods
  @methods
end

#typeObject (readonly)

Returns the value of attribute type.



4
5
6
# File 'lib/steep/interface/instantiated.rb', line 4

def type
  @type
end

Instance Method Details

#==(other) ⇒ Object



18
19
20
# File 'lib/steep/interface/instantiated.rb', line 18

def ==(other)
  other.is_a?(self.class) && other.type == type && other.params == params && other.methods == methods && other.ivars == ivars
end

#ivarsObject



14
15
16
# File 'lib/steep/interface/instantiated.rb', line 14

def ivars
  @ivars ||= ivar_chains.transform_values(&:type)
end

#select_method_type(&block) ⇒ Object



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/steep/interface/instantiated.rb', line 107

def select_method_type(&block)
  self.class.new(
    type: type,
    methods: methods.each.with_object({}) do |(name, method), methods|
      methods[name] = Method.new(
        type_name: method.type_name,
        name: method.name,
        types: method.types.select(&block),
        super_method: method.super_method,
        attributes: method.attributes,
      )
    end.reject do |_, method|
      method.types.empty?
    end,
    ivar_chains: ivar_chains
  )
end

#validate(check) ⇒ Object



54
55
56
57
58
59
60
61
62
# File 'lib/steep/interface/instantiated.rb', line 54

def validate(check)
  methods.each do |_, method|
    validate_method(check, method)
  end

  ivar_chains.each do |name, chain|
    validate_chain(check, name, chain)
  end
end

#validate_chain(check, name, chain) ⇒ Object



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/steep/interface/instantiated.rb', line 64

def validate_chain(check, name, chain)
  return unless chain.parent

  this_type = chain.type
  super_type = chain.parent.type

  case
  when this_type.is_a?(AST::Types::Any) && super_type.is_a?(AST::Types::Any)
    # ok
  else
    relation = Subtyping::Relation.new(sub_type: this_type, super_type: super_type)

    result1 = check.check(relation, constraints: Subtyping::Constraints.empty)
    result2 = check.check(relation.flip, constraints: Subtyping::Constraints.empty)

    if result1.failure? || result2.failure? || this_type.is_a?(AST::Types::Any) || super_type.is_a?(AST::Types::Any)
      raise InvalidIvarOverrideError.new(type: self.type, ivar_name: name, current_ivar_type: this_type, super_ivar_type: super_type)
    end
  end

  validate_chain(check, name, chain.parent)
end

#validate_method(check, method) ⇒ Object



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/steep/interface/instantiated.rb', line 87

def validate_method(check, method)
  if method.super_method
    result = check.check_method(method.name,
                                method,
                                method.super_method,
                                assumption: Set.new,
                                trace: Subtyping::Trace.new,
                                constraints: Subtyping::Constraints.empty)

    if result.success?
      validate_method(check, method.super_method)
    else
      raise InvalidMethodOverrideError.new(type: type,
                                           current_method: method,
                                           super_method: method.super_method,
                                           result: result)
    end
  end
end