Class: RBS::VarianceCalculator
Relationships & Source Files | |
Namespace Children | |
Classes:
| |
Inherits: | Object |
Defined in: | lib/rbs/variance_calculator.rb |
Class Method Summary
- .new(builder:) ⇒ VarianceCalculator constructor
Instance Attribute Summary
- #builder readonly
Instance Method Summary
Constructor Details
.new(builder:) ⇒ VarianceCalculator
# File 'lib/rbs/variance_calculator.rb', line 61
def initialize(builder:) @builder = builder end
Instance Attribute Details
#builder (readonly)
[ GitHub ]# File 'lib/rbs/variance_calculator.rb', line 59
attr_reader :builder
Instance Method Details
#env
[ GitHub ]# File 'lib/rbs/variance_calculator.rb', line 65
def env builder.env end
#in_inherit(name:, args:, variables:)
[ GitHub ]# File 'lib/rbs/variance_calculator.rb', line 88
def in_inherit(name:, args:, variables:) type = if name.class? Types::ClassInstance.new(name: name, args: args, location: nil) else Types::Interface.new(name: name, args: args, location: nil) end Result.new(variables: variables).tap do |result| type(type, result: result, context: :covariant) end end
#in_method_type(method_type:, variables:)
[ GitHub ]# File 'lib/rbs/variance_calculator.rb', line 69
def in_method_type(method_type:, variables:) result = Result.new(variables: variables) method_type.type.each_param do |param| type(param.type, result: result, context: :contravariant) end if block = method_type.block block.type.each_param do |param| type(param.type, result: result, context: :covariant) end type(block.type.return_type, result: result, context: :contravariant) end type(method_type.type.return_type, result: result, context: :covariant) result end
#type(type, result:, context:)
[ GitHub ]# File 'lib/rbs/variance_calculator.rb', line 100
def type(type, result:, context:) case type when Types::Variable if result.include?(type.name) case context when :covariant result.covariant(type.name) when :contravariant result.contravariant(type.name) when :invariant result.invariant(type.name) end end when Types::ClassInstance, Types::Interface NoTypeFoundError.check!(type.name, env: env, location: type.location) type_params = case type when Types::ClassInstance env.class_decls[type.name].type_params when Types::Interface env.interface_decls[type.name].decl.type_params end type.args.each.with_index do |ty, i| var = type_params.params[i] case var&.variance when :invariant type(ty, result: result, context: :invariant) when :covariant type(ty, result: result, context: context) when :contravariant # @type var con: variance con = case context when :invariant :invariant when :covariant :contravariant when :contravariant :covariant else raise end type(ty, result: result, context: con) end end when Types::Tuple, Types::Record, Types::Union, Types::Intersection # Covariant types type.each_type do |ty| type(ty, result: result, context: context) end end end