# frozen_string_literal: true require "rbs" require "pp" module RBS module Test module Hook OPERATORS = { :[] => "indexlookup", :[]= => "indexset", :== => "eqeq", :=== => "eqeqeq", :!= => "noteq", :+ => "plus", :- => "minus", :* => "star", :/ => "slash", :> => "gt", :>= => "gteq", :< => "lt", :<= => "lteq", :<=> => "ufo", :& => "amp", :| => "vbar", :^ => "hat", :! => "not", :<< => "lshift", :>> => "rshift", :~ => "tilda", :=~ => "eqtilda", :% => "percent", :+@ => "unary_plus", :-@ => "unary_minus" } def self.alias_names(target, random) suffix = "#{RBS::Test.suffix}_#{random}" case target when *OPERATORS.keys name = OPERATORS[target] [ "#{name}____with__#{suffix}", "#{name}____without__#{suffix}" ] else aliased_target, punctuation = target.to_s.sub(/([?!=])$/, ''), $1 [ "#{aliased_target}__with__#{suffix}#{punctuation}", "#{aliased_target}__without__#{suffix}#{punctuation}" ] end end def self.setup_alias_method_chain(klass, target, random:) with_method, without_method = alias_names(target, random) RBS.logger.debug "alias name: #{target}, #{with_method}, #{without_method}" klass.instance_eval do alias_method without_method, target alias_method target, with_method case when public_method_defined?(without_method) public target when protected_method_defined?(without_method) protected target when private_method_defined?(without_method) private target end end end def self.hook_method_source(prefix, method_name, key, random:, params:) with_name, without_name = alias_names(method_name, random) full_method_name = "#{prefix}#{method_name}" param_source = params.take_while {|param| param[0] == :req } .map.with_index {|pair, index| pair[1] || "__req__#{random}__#{index}" } param_source.push("*rest_args__#{random}") block_param = "block__#{random}" RBS.logger.debug { "Generating method definition: def #{with_name}(#{param_source.join(", ")}, &#{block_param}) ..." } [__LINE__ + 1, <