class LIT::TypeChecker
@api private @since 0.1.0
Constants
- AST
- PRIMITIVE_TYPE_NAMESPACE
Public Class Methods
new(mod)
click to toggle source
# File lib/lit/type_checker.rb, line 10 def initialize(mod) @mod = mod end
Public Instance Methods
check_type!(type, value)
click to toggle source
# File lib/lit/type_checker.rb, line 14 def check_type!(type, value) is_primitive = if type.is_a?(Module) type.name.include?(PRIMITIVE_TYPE_NAMESPACE) else type.class.name.include?(PRIMITIVE_TYPE_NAMESPACE) end if is_primitive check_primitive_type!(type, value) elsif type.is_a?(AST::Type::Alias) check_type_alias!(type.name, value) else raise InvalidTypeError, "invalid type: #{type}" end end
Private Instance Methods
check_primitive_type!(type, value)
click to toggle source
rubocop:disable Metrics/MethodLength
# File lib/lit/type_checker.rb, line 34 def check_primitive_type!(type, value) if type == AST::Type::Primitive::String unless value.is_a?(String) raise TypeError, "expected #{value} to be a String" end elsif type == AST::Type::Primitive::Integer unless value.is_a?(Integer) raise TypeError, "expected #{value} to be an Integer" end elsif type == AST::Type::Primitive::Float unless value.is_a?(Float) raise TypeError, "expected #{value} to be a Float" end elsif type == AST::Type::Primitive::Boolean unless value == true || value == false raise TypeError, "expected #{value} to be a Boolean" end elsif type == AST::Type::Primitive::Unit unless value.nil? raise TypeError, "expected #{value} to be a Unit (nil)" end elsif type.is_a?(AST::Type::Primitive::Option) if value.is_a?(::LIT::Object::Option::Some) check_primitive_type!(type.type, value.value) elsif value == ::LIT::Object::Option::None # ok else raise TypeError, "expected #{value} to be an instance of Option" end elsif type.is_a?(AST::Type::Primitive::Array) if value.is_a?(::LIT::Object::Array) value.each { |v| check_primitive_type!(type.type, v) } else raise TypeError, "expected #{value} to be an array" end elsif type.is_a?(AST::Type::Primitive::Map) if value.is_a?(::LIT::Object::Map) value.values.each do |(k, v)| check_primitive_type!(type.key_type, k) check_primitive_type!(type.value_type, v) end else raise TypeError, "expected #{value} to be a Map" end elsif type.is_a?(AST::Type::Alias) check_type_alias!(type.name, value) else raise InvalidTypeError, "invalid primitive type: #{type}" end end
check_type_alias!(name, value)
click to toggle source
rubocop:enable Metrics/MethodLength
# File lib/lit/type_checker.rb, line 86 def check_type_alias!(name, value) const = @mod.const_get(name) if const <= Object::Enum unless value.respond_to?(:__parent__) && value.__parent__ == const raise TypeError, "expected #{value} to be of type #{name}" end elsif const <= Object::Struct # ok (checked upon struct initialization) elsif const <= Object::Option type = const.const_get("TYPE") check_type!(type, value) elsif const <= Object::Map type = const.const_get("TYPE") check_type!(type, value) elsif const <= Object::Array type = const.const_get("TYPE") check_type!(type, value) else type = const.const_get("TYPE") check_primitive_type!(type, value) end end