diff options
Diffstat (limited to 'lib/rubygems/core_ext/kernel_warn.rb')
| -rw-r--r-- | lib/rubygems/core_ext/kernel_warn.rb | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/lib/rubygems/core_ext/kernel_warn.rb b/lib/rubygems/core_ext/kernel_warn.rb new file mode 100644 index 0000000000..f806b77fab --- /dev/null +++ b/lib/rubygems/core_ext/kernel_warn.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +module Kernel + rubygems_path = "#{__dir__}/" # Frames to be skipped start with this path. + + original_warn = instance_method(:warn) + + remove_method :warn + + class << self + remove_method :warn + end + + module_function define_method(:warn) {|*messages, **kw| + unless uplevel = kw[:uplevel] + return original_warn.bind_call(self, *messages, **kw) + end + + # Ensure `uplevel` fits a `long` + uplevel, = [uplevel].pack("l!").unpack("l!") + + if uplevel >= 0 + start = 0 + while uplevel >= 0 + loc, = caller_locations(start, 1) + unless loc + # No more backtrace + start += uplevel + break + end + + start += 1 + + next unless path = loc.path + unless path.start_with?(rubygems_path, "<internal:") + # Non-rubygems frames + uplevel -= 1 + end + end + kw[:uplevel] = start + end + + original_warn.bind_call(self, *messages, **kw) + } +end |
