class Tapioca::Dsl::Compilers::UrlHelpers

~~~
end
include GeneratedUrlHelpersModule
include GeneratedPathHelpersModule
class Post
# typed: true
# post.rbi
~~~rbi
~~~
end
def new_index_url(*args); end
sig { params(args: T.untyped).returns(String) }
def index_url(*args); end
sig { params(args: T.untyped).returns(String) }
def edit_index_url(*args); end
sig { params(args: T.untyped).returns(String) }
include ActionDispatch::Routing::UrlFor
include ActionDispatch::Routing::PolymorphicRoutes
module GeneratedUrlHelpersModule
# typed: true
# generated_url_helpers_module.rbi
~~~rbi
~~~
end
def new_index_path(*args); end
sig { params(args: T.untyped).returns(String) }
def index_path(*args); end
sig { params(args: T.untyped).returns(String) }
def edit_index_path(*args); end
sig { params(args: T.untyped).returns(String) }
include ActionDispatch::Routing::UrlFor
include ActionDispatch::Routing::PolymorphicRoutes
module GeneratedPathHelpersModule
# typed: true
# generated_path_helpers_module.rbi
~~~rbi
this compiler will produce the following RBI files:
~~~
end
T.unsafe(self).include Rails.application.routes.url_helpers
# static type checking will work as expected.
# compiler will generate the proper RBI files for the include,
# at runtime but Sorbet won’t see the include. However, since this
# module being included. This allows the ‘include` to happen properly
# Use `T.unsafe` so that Sorbet does not complain about a dynamic
class Post
app/models/post.rb
~~~rb
~~~
end
end
resource :index
routes.draw do
class Application < Rails::Application
# config/application.rb
~~~rb
For example, with the following setup:<br><br>(api.rubyonrails.org/v5.1.7/classes/ActionDispatch/Routing/UrlFor.html#module-ActionDispatch::Routing::UrlFor-label-URL+generation+for+named+routes).
`Tapioca::Dsl::Compilers::UrlHelpers` generates RBI files for classes that include or extend

def create_mixins_for(mod, helper_module)

def create_mixins_for(mod, helper_module)
  include_helper = constant.ancestors.include?(helper_module) || NON_DISCOVERABLE_INCLUDERS.include?(constant)
  extend_helper = constant.singleton_class.ancestors.include?(helper_module)
  mod.create_include(T.must(helper_module.name)) if include_helper
  mod.create_extend(T.must(helper_module.name)) if extend_helper
end

def decorate

def decorate
  case constant
  when GeneratedPathHelpersModule.singleton_class, GeneratedUrlHelpersModule.singleton_class
    generate_module_for(root, constant)
  else
    root.create_path(constant) do |mod|
      create_mixins_for(mod, GeneratedUrlHelpersModule)
      create_mixins_for(mod, GeneratedPathHelpersModule)
    end
  end
end

def gather_constants

def gather_constants
  return [] unless defined?(Rails.application) && Rails.application
  # Load routes if they haven't been loaded yet (see https://github.com/rails/rails/pull/51614).
  routes_reloader = Rails.application.routes_reloader
  routes_reloader.execute_unless_loaded if routes_reloader&.respond_to?(:execute_unless_loaded)
  url_helpers_module = Rails.application.routes.named_routes.url_helpers_module
  path_helpers_module = Rails.application.routes.named_routes.path_helpers_module
  Object.const_set(:GeneratedUrlHelpersModule, url_helpers_module)
  Object.const_set(:GeneratedPathHelpersModule, path_helpers_module)
  constants = all_modules.select do |mod|
    next unless name_of(mod)
    # Fast-path to quickly disqualify most cases
    next false unless url_helpers_module > mod || # rubocop:disable Style/InvertibleUnlessCondition
      path_helpers_module > mod ||
      url_helpers_module > mod.singleton_class ||
      path_helpers_module > mod.singleton_class
    includes_helper?(mod, url_helpers_module) ||
      includes_helper?(mod, path_helpers_module) ||
      includes_helper?(mod.singleton_class, url_helpers_module) ||
      includes_helper?(mod.singleton_class, path_helpers_module)
  end
  constants.concat(NON_DISCOVERABLE_INCLUDERS).push(GeneratedUrlHelpersModule, GeneratedPathHelpersModule)
end

def gather_non_discoverable_includers

def gather_non_discoverable_includers
  [].tap do |includers|
    if defined?(ActionController::TemplateAssertions) && defined?(ActionDispatch::IntegrationTest)
      includers << ActionDispatch::IntegrationTest
    end
    if defined?(ActionView::Helpers)
      includers << ActionView::Helpers
    end
  end.freeze
end

def generate_module_for(root, constant)

def generate_module_for(root, constant)
  root.create_module(T.must(constant.name)) do |mod|
    mod.create_include("::ActionDispatch::Routing::UrlFor")
    mod.create_include("::ActionDispatch::Routing::PolymorphicRoutes")
    constant.instance_methods(false).each do |method|
      mod.create_method(
        method.to_s,
        parameters: [create_rest_param("args", type: "T.untyped")],
        return_type: "String",
      )
    end
  end
end

def includes_helper?(mod, helper)

def includes_helper?(mod, helper)
ors = ancestors_of(mod)
cestors = if Class === mod && (superclass = superclass_of(mod))
ese ancestors are unique to `mod`, and exclude those in common with `superclass`.
stors.take(ancestors.count - ancestors_of(superclass).size)
stors
cestors.include?(helper)