Module: Anyway::RBSGenerator

Included in:
Config
Defined in:
lib/anyway/rbs.rb,
sig/anyway_config.rbs

Constant Summary collapse

TYPE_TO_CLASS =
{
  string: "String",
  integer: "Integer",
  float: "Float",
  date: "Date",
  datetime: "DateTime",
  uri: "URI",
  boolean: "bool"
}.freeze

Instance Method Summary collapse

Instance Method Details

#to_rbsString

Generate RBS signature from a config class

Returns:

  • (String)


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
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
# File 'lib/anyway/rbs.rb', line 16

def to_rbs
  *namespace, class_name = name.split("::")

  buf = []
  indent = 0
  interface_name = "_Config"

  if namespace.empty?
    interface_name = "_#{class_name}"
  else
    buf << "module #{namespace.join("::")}"
    indent += 1
  end

  # Using interface emulates a module we include to provide getters and setters
  # (thus making `super` possible)
  buf << "#{"  " * indent}interface #{interface_name}"
  indent += 1

  # Generating setters and getters for config attributes
  config_attributes.each do |param|
    type = coercion_mapping[param] || defaults[param.to_s]

    type =
      case type
      in NilClass
        "untyped"
      in Symbol
        TYPE_TO_CLASS.fetch(type) { defaults[param] ? "Symbol" : "untyped" }
      in Array
        "Array[untyped]"
      in array: _, type:, **nil
        "Array[#{TYPE_TO_CLASS.fetch(type, "untyped")}]"
      in Hash
        "Hash[string,untyped]"
      in TrueClass | FalseClass
        "bool"
      else
        type.class.to_s
      end

    getter_type = type
    getter_type = "#{type}?" unless required_attributes.include?(param)

    buf << "#{"  " * indent}def #{param}: () -> #{getter_type}"
    buf << "#{"  " * indent}def #{param}=: (#{type}) -> void"

    if type == "bool" || type == "bool?"
      buf << "#{"  " * indent}def #{param}?: () -> #{getter_type}"
    end
  end

  indent -= 1
  buf << "#{"  " * indent}end"

  buf << ""

  buf << "#{"  " * indent}class #{class_name} < #{superclass.name}"
  indent += 1

  buf << "#{"  " * indent}include #{interface_name}"

  indent -= 1
  buf << "#{"  " * indent}end"

  unless namespace.empty?
    buf << "end"
  end

  buf << ""

  buf.join("\n")
end