-
Notifications
You must be signed in to change notification settings - Fork 135
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
5,717 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
# typed: strict | ||
# frozen_string_literal: true | ||
|
||
begin | ||
require "kredis" | ||
rescue LoadError | ||
return | ||
end | ||
|
||
module Tapioca | ||
module Dsl | ||
module Compilers | ||
# `Tapioca::Dsl::Compilers::Kredis` decorates RBI files for all | ||
# classes that include [`Kredis::Attributes`](https://github.com/rails/kredis/blob/main/lib/kredis/attributes.rb). | ||
# | ||
# For example, with the following class: | ||
# | ||
# ~~~rb | ||
# class Person < ApplicationRecord | ||
# kredis_list :names | ||
# kredis_flag :awesome | ||
# kredis_counter :steps, expires_in: 1.hour | ||
# kredis_enum :morning, values: %w[ bright blue black ], default: "bright" | ||
# end | ||
# ~~~ | ||
# | ||
# this compiler will produce an RBI file with the following content: | ||
# ~~~rbi | ||
# # typed: true | ||
# | ||
# class Person | ||
# module GeneratedKredisAttributeMethods | ||
# sig { returns(Kredis::Types::Flag) } | ||
# def awesome; end | ||
# | ||
# sig { returns(T::Boolean) } | ||
# def awesome?; end | ||
# | ||
# sig { returns(PrivateEnumMorning) } | ||
# def morning; end | ||
# | ||
# sig { returns(Kredis::Types::List) } | ||
# def names; end | ||
# | ||
# sig { returns(Kredis::Types::Counter) } | ||
# def steps; end | ||
# | ||
# class PrivateEnumMorning < Kredis::Types::Enum | ||
# sig { void } | ||
# def black!; end | ||
# | ||
# sig { returns(T::Boolean) } | ||
# def black?; end | ||
# | ||
# sig { void } | ||
# def blue!; end | ||
# | ||
# sig { returns(T::Boolean) } | ||
# def blue?; end | ||
# | ||
# sig { void } | ||
# def bright!; end | ||
# | ||
# sig { returns(T::Boolean) } | ||
# def bright?; end | ||
# end | ||
# end | ||
# end | ||
# ~~~ | ||
class Kredis < Compiler | ||
extend T::Sig | ||
|
||
ConstantType = type_member { { fixed: T.all(Class, ::Kredis::Attributes::ClassMethods, Extensions::Kredis) } } | ||
|
||
sig { override.void } | ||
def decorate | ||
return if constant.__tapioca_kredis_types.nil? | ||
|
||
module_name = "GeneratedKredisAttributeMethods" | ||
|
||
root.create_path(constant) do |model| | ||
model.create_module(module_name) do |mod| | ||
constant.__tapioca_kredis_types.each do |method, data| | ||
generate_methods(mod, method, data) | ||
end | ||
end | ||
model.create_include(module_name) | ||
end | ||
end | ||
|
||
class << self | ||
extend T::Sig | ||
|
||
sig { override.returns(T::Enumerable[Module]) } | ||
def gather_constants | ||
all_classes | ||
.grep(::Kredis::Attributes::ClassMethods) | ||
.reject { |klass| klass.to_s == "ActiveRecord::Base" || klass.try(:abstract_class?) } | ||
end | ||
end | ||
|
||
private | ||
|
||
sig { params(mod: RBI::Scope, method: String, data: T::Hash[Symbol, T.untyped]).void } | ||
def generate_methods(mod, method, data) | ||
return_type = data.fetch(:type) | ||
case return_type | ||
when "Kredis::Types::Enum" | ||
klass_name = "PrivateEnum#{method.split("_").map(&:capitalize).join}" | ||
create_enum_class(mod, klass_name, data.fetch(:values)) | ||
return_type = klass_name | ||
when "Kredis::Types::Flag" | ||
mod.create_method("#{method}?", return_type: "T::Boolean") | ||
end | ||
|
||
mod.create_method(method, return_type: return_type) | ||
end | ||
|
||
sig { params(mod: RBI::Scope, klass_name: String, values: T::Array[T.untyped]).void } | ||
def create_enum_class(mod, klass_name, values) | ||
klass = mod.create_class(klass_name, superclass_name: "Kredis::Types::Enum") | ||
values.each do |value| | ||
klass.create_method("#{value}!", return_type: "void") | ||
klass.create_method("#{value}?", return_type: "T::Boolean") | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
# typed: true | ||
# frozen_string_literal: true | ||
|
||
begin | ||
require "kredis" | ||
rescue LoadError | ||
return | ||
end | ||
|
||
module Tapioca | ||
module Dsl | ||
module Compilers | ||
module Extensions | ||
module Kredis | ||
attr_reader :__tapioca_kredis_types | ||
|
||
def kredis_proxy(name, key: nil, config: :shared, after_change: nil) | ||
collect_kredis_type(name, "Kredis::Types::Proxy") | ||
super | ||
end | ||
|
||
def kredis_string(name, key: nil, config: :shared, after_change: nil, expires_in: nil) | ||
collect_kredis_type(name, "Kredis::Types::Scalar") | ||
super | ||
end | ||
|
||
def kredis_integer(name, key: nil, config: :shared, after_change: nil, expires_in: nil) | ||
collect_kredis_type(name, "Kredis::Types::Scalar") | ||
super | ||
end | ||
|
||
def kredis_decimal(name, key: nil, config: :shared, after_change: nil, expires_in: nil) | ||
collect_kredis_type(name, "Kredis::Types::Scalar") | ||
super | ||
end | ||
|
||
def kredis_datetime(name, key: nil, config: :shared, after_change: nil, expires_in: nil) | ||
collect_kredis_type(name, "Kredis::Types::Scalar") | ||
super | ||
end | ||
|
||
def kredis_flag(name, key: nil, config: :shared, after_change: nil, expires_in: nil) | ||
collect_kredis_type(name, "Kredis::Types::Flag") | ||
super | ||
end | ||
|
||
def kredis_float(name, key: nil, config: :shared, after_change: nil, expires_in: nil) | ||
collect_kredis_type(name, "Kredis::Types::Scalar") | ||
super | ||
end | ||
|
||
def kredis_enum(name, key: nil, values:, default:, config: :shared, after_change: nil) | ||
collect_kredis_type(name, "Kredis::Types::Enum", values: values) | ||
super | ||
end | ||
|
||
def kredis_json(name, key: nil, config: :shared, after_change: nil, expires_in: nil) | ||
collect_kredis_type(name, "Kredis::Types::Scalar") | ||
super | ||
end | ||
|
||
def kredis_list(name, key: nil, typed: :string, config: :shared, after_change: nil) | ||
collect_kredis_type(name, "Kredis::Types::List") | ||
super | ||
end | ||
|
||
def kredis_unique_list(name, limit: nil, key: nil, typed: :string, config: :shared, after_change: nil) | ||
collect_kredis_type(name, "Kredis::Types::UniqueList") | ||
super | ||
end | ||
|
||
def kredis_set(name, key: nil, typed: :string, config: :shared, after_change: nil) | ||
collect_kredis_type(name, "Kredis::Types::Set") | ||
super | ||
end | ||
|
||
def kredis_slot(name, key: nil, config: :shared, after_change: nil) | ||
collect_kredis_type(name, "Kredis::Types::Slots") | ||
super | ||
end | ||
|
||
def kredis_slots(name, available:, key: nil, config: :shared, after_change: nil) | ||
collect_kredis_type(name, "Kredis::Types::Slots") | ||
super | ||
end | ||
|
||
def kredis_counter(name, key: nil, config: :shared, after_change: nil, expires_in: nil) | ||
collect_kredis_type(name, "Kredis::Types::Counter") | ||
super | ||
end | ||
|
||
def kredis_hash(name, key: nil, typed: :string, config: :shared, after_change: nil) | ||
collect_kredis_type(name, "Kredis::Types::Hash") | ||
super | ||
end | ||
|
||
def kredis_boolean(name, key: nil, config: :shared, after_change: nil, expires_in: nil) | ||
collect_kredis_type(name, "Kredis::Types::Scalar") | ||
super | ||
end | ||
|
||
private | ||
|
||
def collect_kredis_type(method, type, values: nil) | ||
@__tapioca_kredis_types ||= {} | ||
@__tapioca_kredis_types[method.to_s] = { type: type, values: values } | ||
end | ||
|
||
::Kredis::Attributes::ClassMethods.prepend(self) | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
## Kredis | ||
|
||
`Tapioca::Dsl::Compilers::Kredis` decorates RBI files for all | ||
classes that include [`Kredis::Attributes`](https://github.com/rails/kredis/blob/main/lib/kredis/attributes.rb). | ||
|
||
For example, with the following class: | ||
|
||
~~~rb | ||
class Person < ApplicationRecord | ||
kredis_list :names | ||
kredis_flag :awesome | ||
kredis_counter :steps, expires_in: 1.hour | ||
kredis_enum :morning, values: %w[ bright blue black ], default: "bright" | ||
end | ||
~~~ | ||
|
||
this compiler will produce an RBI file with the following content: | ||
~~~rbi | ||
# typed: true | ||
|
||
class Person | ||
module GeneratedKredisAttributeMethods | ||
sig { returns(Kredis::Types::Flag) } | ||
def awesome; end | ||
|
||
sig { returns(T::Boolean) } | ||
def awesome?; end | ||
|
||
sig { returns(PrivateEnumMorning) } | ||
def morning; end | ||
|
||
sig { returns(Kredis::Types::List) } | ||
def names; end | ||
|
||
sig { returns(Kredis::Types::Counter) } | ||
def steps; end | ||
|
||
class PrivateEnumMorning < Kredis::Types::Enum | ||
sig { void } | ||
def black!; end | ||
|
||
sig { returns(T::Boolean) } | ||
def black?; end | ||
|
||
sig { void } | ||
def blue!; end | ||
|
||
sig { returns(T::Boolean) } | ||
def blue?; end | ||
|
||
sig { void } | ||
def bright!; end | ||
|
||
sig { returns(T::Boolean) } | ||
def bright?; end | ||
end | ||
end | ||
end | ||
~~~ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.