Skip to content

Commit bc4e6af

Browse files
add a compiler for flag shih tzu
1 parent 0af0803 commit bc4e6af

File tree

5 files changed

+407
-0
lines changed

5 files changed

+407
-0
lines changed

Gemfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ group :development do
1111
gem "minitest-reporters"
1212

1313
gem "attr_json"
14+
gem "flag_shih_tzu"
1415
gem "kaminari-activerecord"
1516
gem "money-rails"
1617
gem "paperclip"

Gemfile.lock

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ GEM
9393
date (3.3.4)
9494
drb (2.2.1)
9595
erubi (1.13.1)
96+
flag_shih_tzu (0.3.23)
9697
globalid (1.2.1)
9798
activesupport (>= 6.1)
9899
i18n (1.14.6)
@@ -292,6 +293,7 @@ PLATFORMS
292293
DEPENDENCIES
293294
attr_json
294295
boba!
296+
flag_shih_tzu
295297
kaminari-activerecord
296298
minitest
297299
minitest-hooks
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
# typed: strict
2+
# frozen_string_literal: true
3+
4+
return unless defined?(FlagShihTzu)
5+
6+
module Tapioca
7+
module Dsl
8+
module Compilers
9+
# `Tapioca::Dsl::Compilers::FlagShihTzu` decorates RBI files for models
10+
# using FlagShihTzu.
11+
#
12+
# For example, with FlagShihTzu installed and the following `ActiveRecord::Base` subclass:
13+
#
14+
# ~~~rb
15+
# class Post < ApplicationRecord
16+
# has_flags(
17+
# 1 => :published,
18+
# 2 => :deleted,
19+
# )
20+
# end
21+
# ~~~
22+
#
23+
# This compiler will produce the RBI file `post.rbi` with the following content:
24+
#
25+
# ~~~rbi
26+
# # post.rbi
27+
# # typed: true
28+
# class Post
29+
# include FlagShihTzu
30+
# include FlagShihTzuGeneratedMethods
31+
#
32+
# module FlagShihTzuGeneratedMethods
33+
# sig { returns(T::Boolean) }
34+
# def published; end
35+
# sig { params(value: T::Boolean).returns(T::Boolean) }
36+
# def published=(value); end
37+
# sig { returns(T::Boolean) }
38+
# def published?; end
39+
#
40+
# sig { returns(T::Boolean) }
41+
# def deleted; end
42+
# sig { params(value: T::Boolean).returns(T::Boolean) }
43+
# def deleted=(value); end
44+
# sig { returns(T::Boolean) }
45+
# def deleted?; end
46+
# end
47+
# end
48+
# ~~~
49+
class FlagShihTzu < Tapioca::Dsl::Compiler
50+
extend T::Sig
51+
52+
ConstantType = type_member { { fixed: T.all(T.class_of(::FlagShihTzu), ::FlagShihTzu::GeneratedClassMethods) } }
53+
54+
InstanceMethodsModuleName = "FlagShihTzuGeneratedMethods"
55+
ClassMethodsModuleName = "::FlagShihTzu"
56+
57+
class << self
58+
extend T::Sig
59+
60+
sig { override.returns(T::Enumerable[Module]) }
61+
def gather_constants
62+
all_classes.select { |c| c < ::FlagShihTzu }
63+
end
64+
end
65+
66+
sig { override.void }
67+
def decorate
68+
return if constant.flag_mapping.blank?
69+
70+
root.create_path(constant) do |klass|
71+
instance_module = RBI::Module.new(InstanceMethodsModuleName)
72+
73+
# has_flags(
74+
# 1 => :warpdrive,
75+
# 2 => shields,
76+
# column: 'features',
77+
# )
78+
constant.flag_mapping.each do |_, flags|
79+
# column: 'features', flags: { warpdrive: ..., shields: ... }
80+
flags.each do |flag_key, _|
81+
# .warpdrive
82+
# .warpdrive=
83+
# .warpdrive?
84+
# .warpdrive_changed?
85+
instance_module.create_method(flag_key.to_s, return_type: "T::Boolean")
86+
instance_module.create_method(
87+
"#{flag_key}=",
88+
parameters: [create_param("value", type: "T::Boolean")],
89+
return_type: "T::Boolean",
90+
)
91+
instance_module.create_method("#{flag_key}?", return_type: "T::Boolean")
92+
instance_module.create_method("#{flag_key}_changed?", return_type: "T::Boolean")
93+
94+
# .not_warpdrive
95+
# .not_warpdrive=
96+
# .not_warpdrive?
97+
instance_module.create_method("not_#{flag_key}", return_type: "T::Boolean")
98+
instance_module.create_method("not_#{flag_key}?", return_type: "T::Boolean")
99+
instance_module.create_method(
100+
"not_#{flag_key}=",
101+
parameters: [create_param("value", type: "T::Boolean")],
102+
return_type: "T::Boolean",
103+
)
104+
105+
# .has_warpdrive?
106+
instance_module.create_method("has_#{flag_key}?", return_type: "T::Boolean")
107+
end
108+
end
109+
110+
klass << instance_module
111+
klass.create_include(ClassMethodsModuleName)
112+
klass.create_include(InstanceMethodsModuleName)
113+
end
114+
end
115+
end
116+
end
117+
end
118+
end

sorbet/rbi/gems/flag_shih_tzu@0.3.23.rbi

Lines changed: 178 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)