Class: RBI::RBS::TypeTranslator

Inherits:
Object
  • Object
show all
Defined in:
lib/rbi/rbs/type_translator.rb

Constant Summary collapse

Options =
MethodTypeTranslator::Options

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options: Options.default) ⇒ TypeTranslator

: (?options: Options) -> void



41
42
43
# File 'lib/rbi/rbs/type_translator.rb', line 41

def initialize(options: Options.default)
  @options = options
end

Class Method Details

.translate(type) ⇒ Object

: (rbs_type) -> Type



33
34
35
# File 'lib/rbi/rbs/type_translator.rb', line 33

def translate(type)
  new.translate(type)
end

Instance Method Details

#translate(type) ⇒ Object

: (rbs_type) -> Type



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/rbi/rbs/type_translator.rb', line 46

def translate(type)
  case type
  when ::RBS::Types::Alias
    translate_type_alias(type)
  when ::RBS::Types::Bases::Any
    Type.untyped
  when ::RBS::Types::Bases::Bool
    Type.boolean
  when ::RBS::Types::Bases::Bottom
    Type.noreturn
  when ::RBS::Types::Bases::Class
    Type.simple("Class")
  when ::RBS::Types::Bases::Instance
    Type.attached_class
  when ::RBS::Types::Bases::Nil
    Type.simple("NilClass")
  when ::RBS::Types::Bases::Self
    Type.self_type
  when ::RBS::Types::Bases::Top
    Type.anything
  when ::RBS::Types::Bases::Void
    Type.void
  when ::RBS::Types::ClassSingleton
    type_arg = type.args.first
    type_parameter = translate(type_arg) if type_arg && !@options.erase_generic_types
    Type.class_of(Type.simple(type.name.to_s), type_parameter)
  when ::RBS::Types::ClassInstance
    translate_class_instance(type)
  when ::RBS::Types::Function
    translate_function(type)
  when ::RBS::Types::Interface
    # TODO: unsupported yet
    # RBS interfaces (like _Foo) don't have a direct Sorbet equivalent
    # and the names aren't valid Ruby identifiers
    Type.untyped
  when ::RBS::Types::Intersection
    Type.all(*type.types.map { |t| translate(t) })
  when ::RBS::Types::Literal
    # Sorbet doesn't support literal types, so map to their base type
    case type.literal
    when nil then Type.simple("NilClass")
    when true then Type.simple("TrueClass")
    when false then Type.simple("FalseClass")
    else
      Type.simple(type.literal.class.to_s)
    end
  when ::RBS::Types::Optional
    Type.nilable(translate(type.type))
  when ::RBS::Types::Proc
    proc = translate(type.type) #: as Type::Proc
    proc.bind(translate(type.self_type)) if type.self_type
    proc
  when ::RBS::Types::Record
    Type.shape(type.all_fields.to_h do |name, (value, required)|
      translated = translate(value)
      [name, required ? translated : Type.nilable(translated)]
    end)
  when ::RBS::Types::Tuple
    Type.tuple(type.types.map { |t| translate(t) })
  when ::RBS::Types::Union
    Type.any(*type.types.map { |t| translate(t) })
  when ::RBS::Types::UntypedFunction
    Type.proc.params(arg0: Type.untyped).returns(Type.untyped)
  when ::RBS::Types::Variable
    if @options.erase_generic_types
      Type.anything
    else
      Type.type_parameter(type.name)
    end
  else
    type #: absurd
  end
end