Class: Keiyaku::Emitter::RBS

Inherits:
Object
  • Object
show all
Defined in:
lib/keiyaku/emitter/rbs.rb

Overview

The signature file, which is a second translation of the same document into a language with its own rules: | means one thing after attr_reader and another after ->, a name that is not a method cannot be an attr_reader at all, and a component that turned out not to be a class is referred to by a type alias rather than by its constant. None of that has anything to do with what the Ruby emitter is deciding, so it is kept where it can be read as the one subject it is.

It is handed the model and union tables rather than a copy of them, because a union component's expansion is worked out while the schemas are still being collected — the tables go on growing behind it.

Constant Summary collapse

SCALARS =
{
  ":bool" => "bool", ":any" => "untyped", ":binary" => "String", ":text" => "String",
  ":upload" => "Keiyaku::Upload | IO"
}.freeze

Instance Method Summary collapse

Constructor Details

#initialize(namespace:, models:, unions:) ⇒ RBS

Returns a new instance of RBS.



24
25
26
27
28
# File 'lib/keiyaku/emitter/rbs.rb', line 24

def initialize(namespace:, models:, unions:)
  @namespace = namespace
  @models = models
  @unions = unions
end

Instance Method Details

#source(order, operations) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/keiyaku/emitter/rbs.rb', line 45

def source(order, operations)
  models = order.map { model_rbs(_1) }
  methods = operations.filter_map { method_rbs(_1) }

  <<~RBS
    #{HEADER}

    module #{@namespace}
    #{models.join("\n\n")}

      class Client < Keiyaku::Client
    #{methods.join("\n")}
      end
    end
  RBS
end

#type_for(source) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/keiyaku/emitter/rbs.rb', line 30

def type_for(source)
  # A recursive type is written as a Proc in the source and as itself here:
  # RBS has no trouble with a class that mentions its own name.
  return type_for(source[/\A-> \{(.*)\}\z/m, 1].strip) if source.start_with?("-> {")
  return "Array[#{type_for(source[1..-2].strip)}]" if source.start_with?("[")
  return "Hash[String, #{type_for(source[/=>(.*)}/m, 1].strip)}]" if source.start_with?("{")

  # A named union is referred to by its alias; an inline one is spelled out.
  if (expansion = @unions[source])
    return source.start_with?("Keiyaku::OneOf[") ? expand_union(expansion) : Keiyaku.snake(source)
  end

  SCALARS[source] || source
end