Module: Laser::Types

Defined in:
lib/laser/types/types.rb

Defined Under Namespace

Classes: Base, ClassObjectType, ClassType, GenericType, SelfType, StructuralType, TupleType, UnionType

Constant Summary

TOP =
ClassType.new('BasicObject', :covariant)
STRING =
ClassObjectType.new('String')
FIXNUM =
ClassObjectType.new('Fixnum')
BIGNUM =
ClassObjectType.new('Bignum')
FLOAT =
ClassObjectType.new('Float')
ARRAY =
ClassObjectType.new('Array')
HASH =
ClassObjectType.new('Hash')
PROC =
ClassObjectType.new('Proc')
NILCLASS =
ClassObjectType.new('NilClass')
TRUECLASS =
ClassObjectType.new('TrueClass')
FALSECLASS =
ClassObjectType.new('FalseClass')
FALSY =
UnionType.new([FALSECLASS, NILCLASS])
BOOLEAN =
UnionType.new([TRUECLASS, FALSECLASS])
BOOL_OR_NIL =
UnionType.new([BOOLEAN, NILCLASS])
BLOCK =
UnionType.new([PROC, NILCLASS])
EMPTY =
UnionType.new([])
EXPECTATIONS =
{'to_s' => Types::STRING,
'to_str' => Types::STRING,
'to_i' => Types::ClassType.new('Integer', :covariant),
'to_int' => Types::ClassType.new('Integer', :covariant),
'to_f' => Types::FLOAT,
'to_a' => Types::ARRAY,
'to_ary' => Types::ARRAY,
'!' => Types::BOOLEAN }

Class Method Summary collapse

Class Method Details

.equal?(t1, t2) ⇒ Boolean

Returns:

  • (Boolean)


34
35
36
# File 'lib/laser/types/types.rb', line 34

def self.equal?(t1, t2)
  t1.possible_classes == t2.possible_classes
end

.optional(t1) ⇒ Object



42
43
44
# File 'lib/laser/types/types.rb', line 42

def self.optional(t1)
  Types::UnionType.new([t1, Types::NILCLASS])
end

.overlap?(t1, t2) ⇒ Boolean

Returns:

  • (Boolean)


38
39
40
# File 'lib/laser/types/types.rb', line 38

def self.overlap?(t1, t2)
  !(t1.possible_classes & t2.possible_classes).empty?
end

.subtype?(sub, top) ⇒ Boolean

All these relations are very inefficient, but they don't show up in profiling, yet.

Subtype relation. Extremely important. Don't mess it up.

Returns:

  • (Boolean)


8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/laser/types/types.rb', line 8

def self.subtype?(sub, top)
  case top
  when ClassObjectType
    sub.possible_classes.all? { |sub_class| sub_class <= top.class_object }
  when ClassType
    if top.variance == :invariant
      klass = top.possible_classes.first
      sub.possible_classes.all? do |sub_class|
        if Analysis::LaserSingletonClass === sub_class
          sub_class <= klass
        else
          sub_class == klass
        end
      end
    else
      sub.possible_classes.subset?(top.possible_classes)
    end
  when UnionType
    sub.member_types.all? do |submember|
      top.member_types.any? { |topmember| subtype?(submember, topmember) }
    end
  else
    sub.possible_classes.subset?(top.possible_classes)
  end
end