Class: Camille::IntersectionPreprocessor

Inherits:
Object
  • Object
show all
Defined in:
lib/camille/intersection_preprocessor.rb

Defined Under Namespace

Classes: TypeNotCompatibleError

Class Method Summary collapse

Class Method Details

.process(left, right) ⇒ Object



6
7
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/camille/intersection_preprocessor.rb', line 6

def process left, right
  if left.instance_of?(Camille::Types::Object) && right.instance_of?(Camille::Types::Object)
    overlapping_keys = left.fields.keys & right.fields.keys

    new_left_fields = []
    new_left_optional_keys = []
    new_right_fields = []
    new_right_optional_keys = []

    (left.fields.keys - overlapping_keys).each do |key|
      new_left_fields << [key, left.fields[key]]
      new_left_optional_keys << key if left.optional_keys.include?(key)
    end

    (right.fields.keys - overlapping_keys).each do |key|
      new_right_fields << [key, right.fields[key]]
      new_right_optional_keys << key if right.optional_keys.include?(key)
    end

    overlapping_keys.map do |key|
      processed_left, processed_right = IntersectionPreprocessor.process(left.fields[key], right.fields[key])
      new_left_fields << [key, processed_left]
      new_right_fields << [key, processed_right]

      if left.optional_keys.include?(key) && right.optional_keys.include?(key)
        new_left_optional_keys << key
        new_right_optional_keys << key
      end
    end

    [
      Camille::Types::Object.new(**(apply_optional_to_fields new_left_fields, new_left_optional_keys).to_h),
      Camille::Types::Object.new(**(apply_optional_to_fields new_right_fields, new_right_optional_keys).to_h)
    ]
  else
    if left.literal == right.literal
      [left, Camille::Types::Any.new]
    else
      raise TypeNotCompatibleError.new "Cannot reconcile type #{left.literal} and type #{right.literal}."
    end
  end
end