diff options
-rw-r--r-- | lib/irb/context.rb | 5 | ||||
-rw-r--r-- | lib/irb/ext/tracer.rb | 60 | ||||
-rw-r--r-- | lib/irb/extend-command.rb | 1 | ||||
-rw-r--r-- | test/irb/test_context.rb | 2 | ||||
-rw-r--r-- | test/irb/test_init.rb | 6 | ||||
-rw-r--r-- | test/irb/test_tracer.rb | 97 |
6 files changed, 116 insertions, 55 deletions
diff --git a/lib/irb/context.rb b/lib/irb/context.rb index ac61b765c0..5b8791c3ba 100644 --- a/lib/irb/context.rb +++ b/lib/irb/context.rb @@ -161,6 +161,11 @@ module IRB private_constant :KEYWORD_ALIASES + def use_tracer=(val) + require_relative "ext/tracer" + @use_tracer = val + end + private def build_completor completor_type = IRB.conf[:COMPLETOR] case completor_type diff --git a/lib/irb/ext/tracer.rb b/lib/irb/ext/tracer.rb index 3eaeb70ef2..53b2e62245 100644 --- a/lib/irb/ext/tracer.rb +++ b/lib/irb/ext/tracer.rb @@ -3,76 +3,30 @@ # irb/lib/tracer.rb - # by Keiju ISHITSUKA([email protected]) # - +# Loading the gem "tracer" will cause it to extend IRB commands with: +# https://github.com/ruby/tracer/blob/v0.2.2/lib/tracer/irb.rb begin require "tracer" rescue LoadError $stderr.puts "Tracer extension of IRB is enabled but tracer gem wasn't found." - module IRB - class Context - def use_tracer=(opt) - # do nothing - end - end - end return # This is about to disable loading below end module IRB - - # initialize tracing function - def IRB.initialize_tracer - Tracer.verbose = false - Tracer.add_filter { - |event, file, line, id, binding, *rests| - /^#{Regexp.quote(@CONF[:IRB_LIB_PATH])}/ !~ file and - File::basename(file) != "irb.rb" - } - end - - class Context - # Whether Tracer is used when evaluating statements in this context. - # - # See +lib/tracer.rb+ for more information. - attr_reader :use_tracer - alias use_tracer? use_tracer - - # Sets whether or not to use the Tracer library when evaluating statements - # in this context. - # - # See +lib/tracer.rb+ for more information. - def use_tracer=(opt) - if opt - Tracer.set_get_line_procs(@irb_path) { - |line_no, *rests| - @io.line(line_no) - } - elsif !opt && @use_tracer - Tracer.off - end - @use_tracer=opt - end - end - class WorkSpace alias __evaluate__ evaluate # Evaluate the context of this workspace and use the Tracer library to # output the exact lines of code are being executed in chronological order. # - # See +lib/tracer.rb+ for more information. - def evaluate(context, statements, file = nil, line = nil) - if context.use_tracer? && file != nil && line != nil - Tracer.on - begin + # See https://github.com/ruby/tracer for more information. + def evaluate(statements, file = __FILE__, line = __LINE__) + if IRB.conf[:USE_TRACER] == true + CallTracer.new(colorize: Color.colorable?).start do __evaluate__(statements, file, line) - ensure - Tracer.off end else - __evaluate__(statements, file || __FILE__, line || __LINE__) + __evaluate__(statements, file, line) end end end - - IRB.initialize_tracer end diff --git a/lib/irb/extend-command.rb b/lib/irb/extend-command.rb index 69d83080df..91ca96e91a 100644 --- a/lib/irb/extend-command.rb +++ b/lib/irb/extend-command.rb @@ -317,7 +317,6 @@ module IRB # :nodoc: @EXTEND_COMMANDS = [ [:eval_history=, "ext/eval_history.rb"], - [:use_tracer=, "ext/tracer.rb"], [:use_loader=, "ext/use-loader.rb"], ] diff --git a/test/irb/test_context.rb b/test/irb/test_context.rb index dad819b4c1..a761521691 100644 --- a/test/irb/test_context.rb +++ b/test/irb/test_context.rb @@ -1,7 +1,7 @@ # frozen_string_literal: false require 'tempfile' require 'irb' -require 'rubygems' if defined?(Gem) +require 'rubygems' require_relative "helper" diff --git a/test/irb/test_init.rb b/test/irb/test_init.rb index 0365098132..64bd96d022 100644 --- a/test/irb/test_init.rb +++ b/test/irb/test_init.rb @@ -216,6 +216,12 @@ module TestIRB assert_equal(['-f'], argv) end + def test_option_tracer + argv = %w[--tracer] + IRB.setup(eval("__FILE__"), argv: argv) + assert_equal(true, IRB.conf[:USE_TRACER]) + end + private def with_argv(argv) diff --git a/test/irb/test_tracer.rb b/test/irb/test_tracer.rb new file mode 100644 index 0000000000..f8da066b63 --- /dev/null +++ b/test/irb/test_tracer.rb @@ -0,0 +1,97 @@ +# frozen_string_literal: false +require 'tempfile' +require 'irb' +require 'rubygems' + +require_relative "helper" + +module TestIRB + class ContextWithTracerIntegrationTest < IntegrationTestCase + def setup + super + + @envs.merge!("NO_COLOR" => "true", "RUBY_DEBUG_HISTORY_FILE" => '') + end + + def example_ruby_file + <<~'RUBY' + class Foo + def self.foo + 100 + end + end + + def bar(obj) + obj.foo + end + + binding.irb + RUBY + end + + def test_use_tracer_is_disabled_by_default + write_rc <<~RUBY + IRB.conf[:USE_TRACER] = false + RUBY + + write_ruby example_ruby_file + + output = run_ruby_file do + type "bar(Foo)" + type "exit!" + end + + assert_nil IRB.conf[:USER_TRACER] + assert_not_include(output, "#depth:") + assert_not_include(output, "Foo.foo") + end + + def test_use_tracer_enabled_when_gem_is_unavailable + begin + gem 'tracer' + omit "Skipping because 'tracer' gem is available." + rescue Gem::LoadError + write_rc <<~RUBY + IRB.conf[:USE_TRACER] = true + RUBY + + write_ruby example_ruby_file + + output = run_ruby_file do + type "bar(Foo)" + type "exit!" + end + + assert_include(output, "Tracer extension of IRB is enabled but tracer gem wasn't found.") + end + end + + def test_use_tracer_enabled_when_gem_is_available + if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('3.1.0') + omit "Ruby version before 3.1.0 does not support Tracer integration. Skipping this test." + end + + begin + gem 'tracer' + rescue Gem::LoadError + omit "Skipping because 'tracer' gem is not available. Enable with WITH_TRACER=true." + end + + write_rc <<~RUBY + IRB.conf[:USE_TRACER] = true + RUBY + + write_ruby example_ruby_file + + output = run_ruby_file do + type "bar(Foo)" + type "exit!" + end + + assert_include(output, "Object#bar at") + assert_include(output, "Foo.foo at") + assert_include(output, "Foo.foo #=> 100") + assert_include(output, "Object#bar #=> 100") + end + end +end |