From 9d76c56df3144a56ddc9adcec0e394860454ecff Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Tue, 17 Feb 2026 15:40:05 -0500 Subject: [PATCH] Use explicit type annotations for CurrentAttributes methods When an explicit type is given for an attributes, e.g. by attribute :user_id #: -> Integer? def user_id = super we should use that type in the class methods rather than untyped. --- .../active_support_current_attributes.rb | 17 ++----- .../active_support_current_attributes_spec.rb | 46 +++++++++++++++++++ 2 files changed, 49 insertions(+), 14 deletions(-) diff --git a/lib/tapioca/dsl/compilers/active_support_current_attributes.rb b/lib/tapioca/dsl/compilers/active_support_current_attributes.rb index 872cb933e..3626bff82 100644 --- a/lib/tapioca/dsl/compilers/active_support_current_attributes.rb +++ b/lib/tapioca/dsl/compilers/active_support_current_attributes.rb @@ -72,11 +72,11 @@ def decorate current_attributes_methods_name = "GeneratedAttributeMethods" current_attributes.create_module(current_attributes_methods_name) do |generated_attribute_methods| dynamic_methods.each do |method| - method = method.to_s + method = constant.instance_method(method) # We want to generate each method both on the class - generate_method(current_attributes, method, class_method: true) + create_method_from_def(current_attributes, method, class_method: true) # and on the instance - generate_method(generated_attribute_methods, method, class_method: false) + create_method_from_def(generated_attribute_methods, method, class_method: false) end instance_methods.each do |method| @@ -110,17 +110,6 @@ def dynamic_methods_of_constant def instance_methods_of_constant constant.instance_methods(false) end - - #: (RBI::Scope klass, String method, class_method: bool) -> void - def generate_method(klass, method, class_method:) - method_def = if class_method - constant.method(method) - else - constant.instance_method(method) - end - - create_method_from_def(klass, method_def, class_method: class_method) - end end end end diff --git a/spec/tapioca/dsl/compilers/active_support_current_attributes_spec.rb b/spec/tapioca/dsl/compilers/active_support_current_attributes_spec.rb index 94fc7810c..5779feed8 100644 --- a/spec/tapioca/dsl/compilers/active_support_current_attributes_spec.rb +++ b/spec/tapioca/dsl/compilers/active_support_current_attributes_spec.rb @@ -142,6 +142,52 @@ def account=(value); end assert_equal(expected, rbi_for(:Current)) end + + it "copies types from instance methods to class methods" do + add_ruby_file("current.rb", <<~RUBY) + class Current < ActiveSupport::CurrentAttributes + extend T::Sig + + attribute :user_id + + sig { returns(T.nilable(Integer)) } + def user_id + super + end + + sig { params(value: T.nilable(Integer)).void } + def user_id=(value) + super + end + end + RUBY + + expected = <<~RBI + # typed: strong + + class Current + include GeneratedAttributeMethods + + class << self + sig { returns(T.nilable(::Integer)) } + def user_id; end + + sig { params(value: T.nilable(::Integer)).void } + def user_id=(value); end + end + + module GeneratedAttributeMethods + sig { returns(T.nilable(::Integer)) } + def user_id; end + + sig { params(value: T.nilable(::Integer)).void } + def user_id=(value); end + end + end + RBI + + assert_equal(expected, rbi_for(:Current)) + end end end end