56 lines
1.8 KiB
Ruby
56 lines
1.8 KiB
Ruby
![]() |
# typed: strict
|
||
|
# frozen_string_literal: true
|
||
|
|
||
|
require_relative "../../../global"
|
||
|
require "sorbet/tapioca/utils"
|
||
|
require "debrew"
|
||
|
|
||
|
module Tapioca
|
||
|
module Compilers
|
||
|
class Attrables < Tapioca::Dsl::Compiler
|
||
|
ATTRABLE_FILENAME = "attrable.rb"
|
||
|
ConstantType = type_member { { fixed: Module } }
|
||
|
|
||
|
sig { override.returns(T::Enumerable[Module]) }
|
||
|
def self.gather_constants
|
||
|
ObjectSpace.each_object(Attrable).map { |obj| obj.name.nil? ? obj.attached_object : obj }
|
||
|
end
|
||
|
|
||
|
sig { override.void }
|
||
|
def decorate
|
||
|
root.create_path(constant) do |klass|
|
||
|
Homebrew::Tapioca::Utils.methods_from_file(constant, ATTRABLE_FILENAME)
|
||
|
.each { |method| compile_attrable_method(klass, method) }
|
||
|
Homebrew::Tapioca::Utils.methods_from_file(constant, ATTRABLE_FILENAME, class_methods: true)
|
||
|
.each { |method| compile_attrable_method(klass, method, class_method: true) }
|
||
|
end
|
||
|
end
|
||
|
|
||
|
private
|
||
|
|
||
|
sig { params(klass: RBI::Scope, method: T.any(Method, UnboundMethod), class_method: T::Boolean).void }
|
||
|
def compile_attrable_method(klass, method, class_method: false)
|
||
|
case method.arity
|
||
|
when -1
|
||
|
# attr_rw
|
||
|
klass.create_method(
|
||
|
method.name.to_s,
|
||
|
parameters: [create_opt_param("arg", type: "T.untyped", default: "nil")],
|
||
|
return_type: "T.untyped",
|
||
|
class_method:,
|
||
|
)
|
||
|
when 0
|
||
|
# attr_predicate
|
||
|
klass.create_method(
|
||
|
method.name.to_s,
|
||
|
return_type: "T::Boolean",
|
||
|
class_method:,
|
||
|
)
|
||
|
else
|
||
|
raise "Unsupported arity for method #{method.name} - did `Attrable` change?"
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|