class Tapioca::Dsl::Compilers::JsonApiClientResource

~~~
end
end
def user_id=(user_id); end
sig { params(user_id: T.nilable(::String)).returns(T.nilable(::String)) }
def user_id; end
sig { returns(T.nilable(::String)) }
def title=(title); end
sig { params(title: T.nilable(::String)).returns(T.nilable(::String)) }
def title; end
sig { returns(T.nilable(::String)) }
module JsonApiClientResourceGeneratedMethods
include JsonApiClientResourceGeneratedMethods
class Post
# typed: strong
# post.rbi
end
end
def posts=(posts); end
sig { params(posts: T.nilable(T::Array)).returns(T.nilable(T::Array)) }
def posts; end
sig { returns(T.nilable(T::Array)) }
def name=(name); end
sig { params(name: T.nilable(::String)).returns(T.nilable(::String)) }
def name; end
sig { returns(T.nilable(::String)) }
def is_admin=(is_admin); end
sig { params(is_admin: T::Boolean).returns(T::Boolean) }
def is_admin; end
sig { returns(T::Boolean) }
module JsonApiClientResourceGeneratedMethods
include JsonApiClientResourceGeneratedMethods
class User
# typed: strong
# user.rbi
~~~rbi
this compiler will produce RBI files with the following content:
~~~
end
property :title, type: :string
belongs_to :user
class Post < JsonApiClient::Resource
# post.rb
end
property :is_admin, type: :boolean, default: false
property :name, type: :string
has_many :posts
class User < JsonApiClient::Resource
# user.rb
~~~rb
For example, with the following classes that inherits ‘:Resource`:<br><br>(github.com/JsonApiClient/json_api_client).
`Tapioca::Dsl::Compilers::JsonApiClientResource` generates RBI files for classes that inherit

def decorate

def decorate
  schema = resource_schema
  return if schema.nil? && constant.associations.empty?
  root.create_path(constant) do |k|
    module_name = "JsonApiClientResourceGeneratedMethods"
    k.create_module(module_name) do |mod|
      schema&.each_property do |property|
        generate_methods_for_property(mod, property)
      end
      constant.associations.each do |association|
        generate_methods_for_association(mod, association)
      end
    end
    k.create_include(module_name)
  end
end

def gather_constants

def gather_constants
  all_modules.select do |c|
    name_of(c) && ::JsonApiClient::Resource > c
  end
end

def generate_methods_for_association(mod, association)

def generate_methods_for_association(mod, association)
  # If the association is broken, it will raise a NameError when trying to access the association_class
  klass = association.association_class
  name, type = case association
  when ::JsonApiClient::Associations::BelongsTo::Association
    # id must be a string: # https://jsonapi.org/format/#document-resource-object-identification
    [association.param.to_s, "T.nilable(::String)"]
  when ::JsonApiClient::Associations::HasOne::Association
    [association.attr_name.to_s, "T.nilable(#{klass})"]
  when ::JsonApiClient::Associations::HasMany::Association
    [association.attr_name.to_s, "T.nilable(T::Array[#{klass}])"]
  else
    return # Unsupported association type
  end
  mod.create_method(name, return_type: type)
  mod.create_method("#{name}=", parameters: [create_param(name, type: type)], return_type: type)
end

def generate_methods_for_property(mod, property)

def generate_methods_for_property(mod, property)
  type = type_for(property)
  name = property.name.to_s
  mod.create_method(name, return_type: type)
  mod.create_method("#{name}=", parameters: [create_param(name, type: type)], return_type: type)
end

def resource_schema

def resource_schema
  schema = constant.schema
  # empty? does not exist on JsonApiClient::Schema
  schema if schema.size > 0 # rubocop:disable Style/ZeroLengthPredicate
end

def type_for(property)

def type_for(property)
  type = ::JsonApiClient::Schema::TypeFactory.type_for(property.type)
  return "T.untyped" if type.nil?
  sorbet_type = if type.respond_to?(:sorbet_type)
    line, file = type.method(:sorbet_type).source_location
    $stderr.puts <<~MESSAGE
      WARNING: `#sorbet_type` is deprecated. Please rename your method to `#__tapioca_type`."
      Defined on line #{line} of #{file}
    MESSAGE
    type.sorbet_type
  elsif type.respond_to?(:__tapioca_type)
    type.__tapioca_type
  elsif type == ::JsonApiClient::Schema::Types::Integer
    "::Integer"
  elsif type == ::JsonApiClient::Schema::Types::String
    "::String"
  elsif type == ::JsonApiClient::Schema::Types::Float
    "::Float"
  elsif type == ::JsonApiClient::Schema::Types::Time
    "::Time"
  elsif type == ::JsonApiClient::Schema::Types::Decimal
    "::BigDecimal"
  elsif type == ::JsonApiClient::Schema::Types::Boolean
    "T::Boolean"
  else
    "T.untyped"
  end
  if property.default.nil?
    as_nilable_type(sorbet_type)
  else
    sorbet_type
  end
end