Class: Tapioca::Compilers::Dsl::ActionControllerHelpers

Inherits:
Base
  • Object
show all
Extended by:
T::Sig
Defined in:
lib/tapioca/compilers/dsl/action_controller_helpers.rb

Overview

`Tapioca::Compilers::Dsl::ActionControllerHelpers` decorates RBI files for all subclasses of [`ActionController::Base`](api.rubyonrails.org/classes/ActionController/Helpers.html).

For example, with the following `MyHelper` module:

~~~rb module MyHelper

 def greet(user)
   # ...
 end

def localized_time
   # ...
 end

end ~~~

and the following controller:

~~~rb class UserController < ActionController::Base

helper MyHelper
helper { def age(user) "99" end }
helper_method :current_user_name

def current_user_name
  # ...
end

end ~~~

this generator will produce an RBI file `user_controller.rbi` with the following content:

~~~rbi # user_controller.rbi # typed: strong class UserController

module HelperMethods
  include MyHelper

  sig { params(user: T.untyped).returns(T.untyped) }
  def age(user); end

  sig { returns(T.untyped) }
  def current_user_name; end
end

class HelperProxy < ::ActionView::Base
  include HelperMethods
end

sig { returns(HelperProxy) }
def helpers; end

end ~~~

Constant Summary

Constants included from Reflection

Reflection::ANCESTORS_METHOD, Reflection::CLASS_METHOD, Reflection::CONSTANTS_METHOD, Reflection::EQUAL_METHOD, Reflection::METHOD_METHOD, Reflection::NAME_METHOD, Reflection::OBJECT_ID_METHOD, Reflection::PRIVATE_INSTANCE_METHODS_METHOD, Reflection::PROTECTED_INSTANCE_METHODS_METHOD, Reflection::PUBLIC_INSTANCE_METHODS_METHOD, Reflection::SINGLETON_CLASS_METHOD, Reflection::SUPERCLASS_METHOD

Instance Attribute Summary

Attributes inherited from Base

#errors, #processable_constants

Instance Method Summary collapse

Methods inherited from Base

#add_error, #handles?, #initialize

Methods included from Reflection

#ancestors_of, #are_equal?, #class_of, #constants_of, #descendants_of, #inherited_ancestors_of, #method_of, #name_of, #name_of_type, #object_id_of, #private_instance_methods_of, #protected_instance_methods_of, #public_instance_methods_of, #qualified_name_of, #signature_of, #singleton_class_of, #superclass_of

Constructor Details

This class inherits a constructor from Tapioca::Compilers::Dsl::Base

Instance Method Details

#decorate(root, constant) ⇒ Object


76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/tapioca/compilers/dsl/action_controller_helpers.rb', line 76

def decorate(root, constant)
  helpers_module = constant._helpers
  proxied_helper_methods = constant._helper_methods.map(&:to_s).map(&:to_sym)

  helper_proxy_name = "HelperProxy"
  helper_methods_name = "HelperMethods"

  # Define the helpers method
  root.create_path(constant) do |controller|
    controller.create_method("helpers", return_type: helper_proxy_name)

    # Create helper method module
    controller.create_module(helper_methods_name) do |helper_methods|
      # If the controller has no helper defined, then it just inherits
      # the Action Controlller base helper methods module, so we should
      # just add that as an include and stop doing more processing.
      if helpers_module.name == "ActionController::Base::HelperMethods"
        next helper_methods.create_include(T.must(qualified_name_of(helpers_module)))
      end

      # Find all the included helper modules and generate an include
      # for each of those helper modules
      gather_includes(helpers_module).each do |ancestor|
        helper_methods.create_include(ancestor)
      end

      # Generate a method definition in the helper module for each
      # helper method defined via the `helper_method` call in the controller.
      helpers_module.instance_methods(false).each do |method_name|
        method = if proxied_helper_methods.include?(method_name)
          helper_method_proxy_target(constant, method_name)
        else
          helpers_module.instance_method(method_name)
        end

        if method
          create_method_from_def(helper_methods, method)
        else
          create_unknown_proxy_method(helper_methods, method_name)
        end
      end
    end

    # Create helper proxy class
    controller.create_class(helper_proxy_name, superclass_name: "::ActionView::Base") do |proxy|
      proxy.create_include(helper_methods_name)
    end
  end
end

#gather_constantsObject


127
128
129
# File 'lib/tapioca/compilers/dsl/action_controller_helpers.rb', line 127

def gather_constants
  descendants_of(::ActionController::Base).reject(&:abstract?).select(&:name)
end