From af3c5bd764e876f507594560eeba8802aa82f382 Mon Sep 17 00:00:00 2001 From: Ufuk Kayserilioglu Date: Thu, 30 Jan 2025 19:33:24 +0000 Subject: [PATCH] Fallback to `Backtrace#path` if `absolute_path` is `nil` --- lib/tapioca/runtime/reflection.rb | 6 +++-- spec/tapioca/gem/pipeline_spec.rb | 44 +++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/lib/tapioca/runtime/reflection.rb b/lib/tapioca/runtime/reflection.rb index 665dc0299..dad82bec4 100644 --- a/lib/tapioca/runtime/reflection.rb +++ b/lib/tapioca/runtime/reflection.rb @@ -210,15 +210,17 @@ def resolve_loc(locations) end return unless resolved_loc + resolved_loc_path = resolved_loc.absolute_path || resolved_loc.path + # Find the location of the last frame in this file to get the most accurate line number. - resolved_loc = locations.find { |loc| loc.absolute_path == resolved_loc.absolute_path } + resolved_loc = locations.find { |loc| loc.absolute_path == resolved_loc_path } return unless resolved_loc # If the last operation was a `require`, and we have no more frames, # we are probably dealing with a C-method. return if locations.first&.label == "require" - file = resolved_loc.absolute_path || "" + file = resolved_loc.absolute_path || resolved_loc.path || "" SourceLocation.from_loc([file, resolved_loc.lineno]) end diff --git a/spec/tapioca/gem/pipeline_spec.rb b/spec/tapioca/gem/pipeline_spec.rb index ae93d6ce3..269dc1e04 100644 --- a/spec/tapioca/gem/pipeline_spec.rb +++ b/spec/tapioca/gem/pipeline_spec.rb @@ -4112,6 +4112,50 @@ module Container::FooModule; end assert_equal(output, compile) end + it "handles class_eval created methods" do + add_ruby_file("container.rb", <<~'RUBY') + class Foo + class_eval <<~EOF + def foo; end + def bar; end + EOF + + class_eval <<~EOF, __FILE__, __LINE__ + 1 + def baz; end + def qux; end + EOF + + # Somehow defining methods in a loop triggers a different behavior + # in backtrace locations where the absolute path ends up being `nil`. + %w[string integer float boolean date datetime decimal money].each do |attr_type| + class_eval <<-EOV, __FILE__, __LINE__ + 1 + def #{attr_type} + end + EOV + end + end + RUBY + + output = template(<<~RBI) + class Foo + def bar; end + def baz; end + def boolean; end + def date; end + def datetime; end + def decimal; end + def float; end + def foo; end + def integer; end + def money; end + def qux; end + def string; end + end + RBI + + assert_equal(output, compile) + end + it "includes comment documentation from sources when doc is true" do add_ruby_file("foo.rb", <<~RUBY) # frozen_string_literal: true