From 5014473f7138066ce2665f80f11d118105a12e5d Mon Sep 17 00:00:00 2001 From: Hashim1999164 <64767361+Hashim1999164@users.noreply.github.com> Date: Wed, 19 Aug 2026 00:51:37 +0500 Subject: [PATCH] Skip ActiveSupport deprecation proxies when gathering DSL constants. --- lib/tapioca/dsl/compiler.rb | 14 +++++++++++++- .../compilers/active_support_concern_spec.rb | 17 +++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/lib/tapioca/dsl/compiler.rb b/lib/tapioca/dsl/compiler.rb index fbe33fcea..e5afac7ac 100644 --- a/lib/tapioca/dsl/compiler.rb +++ b/lib/tapioca/dsl/compiler.rb @@ -75,7 +75,19 @@ def all_modules @@requested_constants.grep(Module) else ObjectSpace.each_object(Module).to_a - end.freeze #: Enumerable[Module[top]]? + end.reject { |mod| deprecated_constant_proxy?(mod) }.freeze #: Enumerable[Module[top]]? + end + + # Rails 8.1+ wraps deprecated constants in DeprecatedConstantProxy, which + # undefines most instance methods and warns from method_missing. Inspecting + # those modules during DSL discovery (is_a?, singleton_class, etc.) emits + # deprecation warnings even though Tapioca is only enumerating ObjectSpace. + # class_of uses Kernel#class so we can recognize the proxy without warning. + #: (Module[top] mod) -> bool + def deprecated_constant_proxy?(mod) + proxy_class_name = name_of(class_of(mod)) + proxy_class_name == "ActiveSupport::Deprecation::DeprecatedConstantProxy" || + proxy_class_name == "ActiveSupport::DeprecatedConstantProxy" end end diff --git a/spec/tapioca/dsl/compilers/active_support_concern_spec.rb b/spec/tapioca/dsl/compilers/active_support_concern_spec.rb index 2b46844e5..ccec51956 100644 --- a/spec/tapioca/dsl/compilers/active_support_concern_spec.rb +++ b/spec/tapioca/dsl/compilers/active_support_concern_spec.rb @@ -14,6 +14,23 @@ def before_setup end describe "gather_constants" do + it "does not gather ActiveSupport deprecation proxies and does not warn" do + require "active_support/concurrency/load_interlock_aware_monitor" + + warnings = [] + previous_behavior = ActiveSupport.deprecator.behavior + ActiveSupport.deprecator.behavior = ->(message, *) { warnings << message.to_s } + + begin + constants = gathered_constants + ensure + ActiveSupport.deprecator.behavior = previous_behavior + end + + refute_includes(constants, "ActiveSupport::Concurrency::LoadInterlockAwareMonitor") + assert_empty(warnings.grep(/LoadInterlockAwareMonitor/)) + end + it "does not gather anonymous constants" do add_ruby_file("test_case.rb", <<~RUBY) module TestCase