Skip to content

Commit 7872cf2

Browse files
committed
Add types to generated RBI files for FrozenRecord
1 parent cadc05f commit 7872cf2

File tree

2 files changed

+114
-1
lines changed

2 files changed

+114
-1
lines changed

lib/tapioca/dsl/compilers/frozen_record.rb

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,17 @@ def decorate
7676
module_name = "FrozenRecordAttributeMethods"
7777

7878
record.create_module(module_name) do |mod|
79+
extra_methods = constant.instance_methods(false) - attributes.to_a.map(&:to_sym)
7980
attributes.each do |attribute|
81+
return_type = compile_method_return_type_to_rbi(constant.instance_method(attribute))
8082
mod.create_method("#{attribute}?", return_type: "T::Boolean")
81-
mod.create_method(attribute.to_s, return_type: "T.untyped")
83+
mod.create_method(attribute.to_s, return_type: return_type)
84+
end
85+
extra_methods.each do |method|
86+
method_def = constant.instance_method(method)
87+
parameters = compile_method_parameters_to_rbi(method_def)
88+
return_type = compile_method_return_type_to_rbi(method_def)
89+
mod.create_method(method.to_s, return_type: return_type, parameters: parameters)
8290
end
8391
end
8492

spec/tapioca/dsl/compilers/frozen_record_spec.rb

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,111 @@ def last_name?; end
9797
assert_equal(expected, rbi_for(:Student))
9898
end
9999

100+
it "can handle annotated fields" do
101+
add_ruby_file("student.rb", <<~RUBY)
102+
# typed: strong
103+
104+
class Student < FrozenRecord::Base
105+
extend(T::Sig)
106+
107+
self.base_path = __dir__
108+
109+
sig { returns(String) }
110+
def first_name
111+
super
112+
end
113+
114+
sig { returns(String) }
115+
def last_name
116+
super
117+
end
118+
119+
sig { returns(String) }
120+
def location
121+
super
122+
end
123+
124+
sig { returns(Integer) }
125+
def age
126+
return super + 5
127+
end
128+
129+
sig { params(grain: Symbol).returns(String) }
130+
def area(grain:)
131+
parts = location.split(',').map(&:strip)
132+
case grain
133+
when :city
134+
parts[0]
135+
when :province
136+
parts[1]
137+
when :country
138+
parts[2]
139+
else
140+
location
141+
end
142+
end
143+
end
144+
RUBY
145+
146+
add_content_file("students.yml", <<~YAML)
147+
- id: 1
148+
first_name: John
149+
last_name: Smith
150+
age: 19
151+
location: Ottawa, Ontario, Canada
152+
- id: 2
153+
first_name: Dan
154+
last_name: Lord
155+
age: 20
156+
location: Toronto, Ontario, Canada
157+
YAML
158+
159+
expected = <<~RBI
160+
# typed: strong
161+
162+
class Student
163+
include FrozenRecordAttributeMethods
164+
165+
module FrozenRecordAttributeMethods
166+
sig { returns(::Integer) }
167+
def age; end
168+
169+
sig { returns(T::Boolean) }
170+
def age?; end
171+
172+
sig { params(grain: ::Symbol).returns(::String) }
173+
def area(grain:); end
174+
175+
sig { returns(::String) }
176+
def first_name; end
177+
178+
sig { returns(T::Boolean) }
179+
def first_name?; end
180+
181+
sig { returns(T.untyped) }
182+
def id; end
183+
184+
sig { returns(T::Boolean) }
185+
def id?; end
186+
187+
sig { returns(::String) }
188+
def last_name; end
189+
190+
sig { returns(T::Boolean) }
191+
def last_name?; end
192+
193+
sig { returns(::String) }
194+
def location; end
195+
196+
sig { returns(T::Boolean) }
197+
def location?; end
198+
end
199+
end
200+
RBI
201+
202+
assert_equal(expected, rbi_for(:Student))
203+
end
204+
100205
it "can handle frozen record scopes" do
101206
add_ruby_file("student.rb", <<~RUBY)
102207
class Student < FrozenRecord::Base

0 commit comments

Comments
 (0)