From b10207df57167790208409c4b65026032626a0d9 Mon Sep 17 00:00:00 2001 From: Stephen Paul Weber Date: Fri, 29 Mar 2019 20:13:26 -0500 Subject: [PATCH] Refactor RecordSelection typecheck --- lib/dhall/typecheck.rb | 45 ++++++++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/lib/dhall/typecheck.rb b/lib/dhall/typecheck.rb index fcaab6e..b7cb95c 100644 --- a/lib/dhall/typecheck.rb +++ b/lib/dhall/typecheck.rb @@ -561,25 +561,44 @@ module Dhall @selector = selection.selector end - def annotate(context) - arecord = TypeChecker.for(@record).annotate(context) + class Selector + def self.for(annotated_record) + if annotated_record.type == Dhall::Variable["Type"] + TypeSelector.new(annotated_record.value) + elsif annotated_record.type.class == Dhall::RecordType + new(annotated_record.type) + else + raise TypeError, "RecordSelection on #{annotated_record.type}" + end + end - fetch_from = if arecord.type == Dhall::Variable["Type"] - normalized = @record.normalize + def initialize(type) + @fetch_from = type.record + end + + def select(selector) + @fetch_from.fetch(selector) do + raise TypeError, "#{@fetch_from} has no field #{@selector}" + end + end + end + + class TypeSelector < Selector + def initialize(union) + normalized = union.normalize TypeChecker.assert normalized, Dhall::UnionType, - "RecordSelection on #{arecord.type}" - normalized.constructor_types - elsif arecord.type.class == Dhall::RecordType - arecord.type.record - else - raise TypeError, "RecordSelection on #{arecord.type}" + "RecordSelection on #{normalized}" + @fetch_from = normalized.constructor_types end + end + + def annotate(context) + arecord = TypeChecker.for(@record).annotate(context) + selector = Selector.for(arecord) Dhall::TypeAnnotation.new( value: @selection.with(record: arecord), - type: fetch_from.fetch(@selector) do - raise TypeError, "#{fetch_from} has no field #{@selector}" - end + type: selector.select(@selector) ) end end -- 2.45.2