Class: Tapioca::Compilers::Shale

Inherits:
Dsl::Compiler
  • Object
show all
Extended by:
T::Sig
Defined in:
lib/tapioca/dsl/compilers/shale.rb

Constant Summary collapse

ConstantType =
type_member { { fixed: T.class_of(::Shale::Mapper) } }
SHALE_ATTRIBUTE_MODULE =
'ShaleAttributeMethods'

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.gather_constantsObject



21
22
23
24
# File 'lib/tapioca/dsl/compilers/shale.rb', line 21

def gather_constants
  # Collect all the classes that inherit from Shale::Mapper
  all_classes.select { |c| c < ::Shale::Mapper }
end

Instance Method Details

#decorateObject



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
# File 'lib/tapioca/dsl/compilers/shale.rb', line 30

def decorate
  # Create a RBI definition for each class that inherits from Shale::Mapper
  root.create_path(constant) do |klass|
    has_shale_builder = includes_shale_builder(constant)
    mod = klass.create_module(SHALE_ATTRIBUTE_MODULE)
    klass.create_include(SHALE_ATTRIBUTE_MODULE)
    # For each attribute defined in the class
    attribute_names = constant.attributes.keys.sort
    attribute_names.each do |attribute_name|
      attribute = T.let(constant.attributes[attribute_name], ::Shale::Attribute)
      non_nilable_type, nilable_type = shale_type_to_sorbet_return_type(attribute)
      type = nilable_type
      if attribute.collection?
        type = "T.nilable(T::Array[#{non_nilable_type}])"
      end
      comments = T.let([], T::Array[RBI::Comment])
      if shale_builder_defined? && attribute.doc
        comments << RBI::Comment.new(T.must(attribute.doc))
      end

      if has_shale_builder && attribute.type < ::Shale::Mapper
        generate_mapper_getter(mod, attribute.name, type, non_nilable_type, comments)
      else
        mod.create_method(attribute.name, return_type: type, comments: comments)
      end

      non_nilable_type, nilable_type = shale_type_to_sorbet_setter_type(attribute)
      type = nilable_type
      if attribute.collection?
        type = "T.nilable(T::Array[#{non_nilable_type}])"
      end

      # setter
      mod.create_method(
        "#{attribute.name}=",
        parameters: [create_param('value', type: type)],
        return_type: type,
        comments: comments,
      )
    end
  end

end

#generate_mapper_getter(mod, method_name, type, non_nilable_type, comments) ⇒ Object



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
119
# File 'lib/tapioca/dsl/compilers/shale.rb', line 83

def generate_mapper_getter(mod, method_name, type, non_nilable_type, comments)
  if mod.respond_to?(:create_sig)
    # for tapioca < 0.16.0
    sigs = T.let([], T::Array[RBI::Sig])
    # simple getter
    sigs << mod.create_sig(
      parameters: { block: 'NilClass' },
      return_type: type,
    )
    # getter with block
    sigs << mod.create_sig(
      parameters: { block: "T.proc.params(arg0: #{non_nilable_type}).void" },
      return_type: non_nilable_type
    )
    mod.create_method_with_sigs(
      method_name,
      sigs: sigs,
      comments: comments,
      parameters: [RBI::BlockParam.new('block')],
    )
  else
    # for tapioca >= 0.16.0
    mod.create_method(method_name, comments: comments) do |method|
      method.add_block_param('block')

      method.add_sig do |sig|
        sig.add_param('block', 'NilClass')
        sig.return_type = type
      end

      method.add_sig do |sig|
        sig.add_param('block', "T.proc.params(arg0: #{non_nilable_type}).void")
        sig.return_type = non_nilable_type
      end
    end
  end
end