8000 Encapsulate backtrace location searching logic to a single method · sorbet/sorbet@65a04c6 · GitHub
[go: up one dir, main page]

Skip to content

Commit 65a04c6

Browse files
paracycleneilparikh
authored andcommitted
Encapsulate backtrace location searching logic to a single method
In order to provide compatibility with TruffleRuby that implements a lot of its core library methods in Ruby, and for future versions of CRuby that is increasingly doing the same, we need to be able to filter all backtrace locations where the `path` starts with `<internal:`. [This gist](https://gist.github.com/eregon/912e6359e83781c5fa1c638d3768c526) shows the current state of the methods implemented in Ruby in CRuby, JRuby and TruffleRuby. Most recently [CRuby started implementing `Array#each` in Ruby](ruby/ruby#9533), making it usages of `each` visible in backtraces with an `<internal:array>` path. This means that in order to be compatible with CRuby 3.4, Sorbet runtime needs to start filtering out backtrace locations that start with `<internal:`. By encapsulating the caller location search logic into a singleton method, we can apply that filtering in a single location and avoid having to repeat it in multiple places.
1 parent dd0bad2 commit 65a04c6

File tree

4 files changed

+19
-7
lines changed

4 files changed

+19
-7
lines changed

gems/sorbet-runtime/lib/sorbet-runtime.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ module T::Private::Types; end
1919
require_relative 'types/configuration'
2020
require_relative 'types/_types'
2121
require_relative 'types/private/decl_state'
22+
require_relative 'types/private/caller_utils'
2223
require_relative 'types/private/class_utils'
2324
require_relative 'types/private/runtime_levels'
2425
require_relative 'types/private/methods/_methods'
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# frozen_string_literal: true
2+
# typed: false
3+
4+
module T::Private::CallerUtils
5+
def self.find_caller(caller_locations)
6+
caller_locations.find do |loc|
7+
next if loc.path&.start_with?("<internal:")
8+
yield loc
9+
end
10+
end
11+
end

gems/sorbet-runtime/lib/types/private/methods/_methods.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ def self._check_final_ancestors(target, target_ancestors, source_method_names, s
168168

169169
definition_file, definition_line = T::Private::Methods.signature_for_method(ancestor.instance_method(method_name)).method.source_location
170170
is_redefined = target == ancestor
171-
caller_loc = caller_locations.find {|l| !l.to_s.start_with?(SORBET_RUNTIME_LIB_PATH)}
171+
caller_loc = T::Private::CallerUtils.find_caller(caller_locations) {|loc| !loc.path.to_s.start_with?(SORBET_RUNTIME_LIB_PATH)}
172172
extra_info = "\n"
173173
if caller_loc
174174
extra_info = (is_redefined ? "Redefined" : "Overridden") + " here: #{caller_loc.path}:#{caller_loc.lineno}\n"

gems/sorbet-runtime/lib/types/private/sealed.rb

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ module T::Private::Sealed
55
module NoInherit
66
def inherited(child)
77
super
8-
this_line = Kernel.caller.find {|line| !line.match(/in `inherited'$/)}
9-
T::Private::Sealed.validate_inheritance(this_line, self, child, 'inherited')
8+
caller_loc = T::Private::CallerUtils.find_caller(caller_locations) {|loc| !loc.to_s.match(/in `inherited'$/)}
9+
T::Private::Sealed.validate_inheritance(caller_loc&.to_s, self, child, 'inherited')
1010
@sorbet_sealed_module_all_subclasses << child
1111
end
1212

@@ -22,15 +22,15 @@ def sealed_subclasses
2222
module NoIncludeExtend
2323
def included(child)
2424
super
25-
this_line = Kernel.caller.find {|line| !line.match(/in `included'$/)}
26-
T::Private::Sealed.validate_inheritance(this_line, self, child, 'included')
25+
caller_loc = T::Private::CallerUtils.find_caller(caller_locations) {|loc| !loc.to_s.match(/in `included'$/)}
26+
T::Private::Sealed.validate_inheritance(caller_loc&.to_s, self, child, 'included')
2727
@sorbet_sealed_module_all_subclasses << child
2828
end
2929

3030
def extended(child)
3131
super
32-
this_line = Kernel.caller.find {|line| !line.match(/in `extended'$/)}
33-
T::Private::Sealed.validate_inheritance(this_line, self, child, 'extended')
32+
caller_loc = T::Private::CallerUtils.find_caller(caller_locations) {|loc| !loc.to_s.match(/in `extended'$/)}
33+
T::Private::Sealed.validate_inheritance(caller_loc&.to_s, self, child, 'extended')
3434
@sorbet_sealed_module_all_subclasses << child
3535
end
3636

0 commit comments

Comments
 (0)
0