File: context.rb

package info (click to toggle)
ruby-byebug 12.0.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,304 kB
  • sloc: ruby: 9,013; ansic: 1,678; sh: 5; makefile: 4
file content (157 lines) | stat: -rw-r--r-- 2,963 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# frozen_string_literal: true

require_relative "frame"
require_relative "helpers/path"
require_relative "helpers/file"
require_relative "processors/command_processor"

module Byebug
  #
  # Mantains context information for the debugger and it's the main
  # communication point between the library and the C-extension through the
  # at_breakpoint, at_catchpoint, at_tracing, at_line and at_return callbacks
  #
  class Context
    include Helpers::FileHelper

    class << self
      include Helpers::PathHelper

      attr_writer :ignored_files

      #
      # List of files byebug will ignore while debugging
      #
      def ignored_files
        @ignored_files ||=
          Byebug.mode == :standalone ? lib_files + [bin_file] : lib_files
      end

      attr_writer :interface

      def interface
        @interface ||= LocalInterface.new
      end

      attr_writer :processor

      def processor
        @processor ||= CommandProcessor
      end
    end

    #
    # Reader for the current frame
    #
    def frame
      @frame ||= Frame.new(self, 0)
    end

    #
    # Writer for the current frame
    #
    def frame=(pos)
      @frame = Frame.new(self, pos)
    end

    extend Forwardable
    def_delegators :frame, :file, :line

    #
    # Current file & line information
    #
    def location
      "#{normalize(file)}:#{line}"
    end

    #
    # Current file, line and source code information
    #
    def full_location
      return location if virtual_file?(file)

      "#{location} #{get_line(file, line)}"
    end

    #
    # Context's stack size
    #
    def stack_size
      return 0 unless backtrace

      backtrace.drop_while { |l| ignored_file?(l.first.path) }
               .take_while { |l| !ignored_file?(l.first.path) }
               .size
    end

    def interrupt
      step_into 1
    end

    #
    # Line handler
    #
    def at_line
      self.frame = 0
      return if ignored_file?(file)

      processor.at_line
    end

    #
    # Tracing handler
    #
    def at_tracing
      return if ignored_file?(file)

      processor.at_tracing
    end

    #
    # Breakpoint handler
    #
    def at_breakpoint(breakpoint)
      processor.at_breakpoint(breakpoint)
    end

    #
    # Catchpoint handler
    #
    def at_catchpoint(exception)
      processor.at_catchpoint(exception)
    end

    #
    # Return handler
    #
    def at_return(return_value)
      return if ignored_file?(file)

      processor.at_return(return_value)
    end

    #
    # End of class definition handler
    #
    def at_end
      return if ignored_file?(file)

      processor.at_end
    end

    private

    def processor
      @processor ||= self.class.processor.new(self, self.class.interface)
    end

    #
    # Tells whether a file is ignored by the debugger.
    #
    # @param path [String] filename to be checked.
    #
    def ignored_file?(path)
      self.class.ignored_files.include?(path)
    end
  end
end