# typed: strict # frozen_string_literal: true require_relative "../../../global" require "cask/url" module Tapioca module Compilers # A compiler for subclasses of Delegator. # To add a new delegator: require it above add add it to the DELEGATIONS hash below. class Delegators < Tapioca::Dsl::Compiler # Mapping of delegator classes to the classes they delegate to (as defined in `__getobj__`). DELEGATIONS = T.let({ Cask::URL => Cask::URL::DSL, }.freeze, T::Hash[Module, Module]) ConstantType = type_member { { fixed: Module } } sig { override.returns(T::Enumerable[Module]) } def self.gather_constants = DELEGATIONS.keys sig { override.void } def decorate root.create_path(constant) do |klass| # Note that `Delegtor` does not subclass `Object`: # https://github.com/ruby/ruby/blob/a6383fb/lib/delegate.rb#L41 # but we assume that we are delegating to a class that does. klass.create_include("Kernel") delegated = DELEGATIONS.fetch(constant) delegated.instance_methods(false).each do |method| signature = T::Utils.signature_for_method(delegated.instance_method(method)) # TODO: handle methods with parameters return_type = signature&.return_type&.to_s || "T.untyped" klass.create_method(method.to_s, return_type:) end end end end end end