linecache-tf 0.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,70 @@
1
+ #!/usr/bin/env ruby
2
+ # $Id: tracelines.rb 182 2009-10-18 23:47:37Z rockyb $
3
+ # Copyright (C) 2007, 2008, 2009 Rocky Bernstein <rockyb@rubyforge.net>
4
+ #
5
+ # This program is free software; you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation; either version 2 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with this program; if not, write to the Free Software
17
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18
+ # 02110-1301 USA.
19
+ require 'thread_frame'
20
+
21
+ module TraceLineNumbers
22
+
23
+ def lnums_for_iseq(iseq, uniq=true)
24
+ lnums = iseq.child_iseqs.map { |iseq|
25
+ iseq.offsetlines.values.flatten
26
+ }.flatten.sort
27
+ uniq ? lnums.uniq : lnums
28
+ end
29
+ module_function :lnums_for_iseq
30
+
31
+ # Return an array of lines numbers that could be
32
+ # stopped at given a file name of a Ruby program.
33
+ def lnums_for_file(file, uniq=true)
34
+ lnums_for_iseq(RubyVM::InstructionSequence::compile_file(file),
35
+ uniq)
36
+ end
37
+ module_function :lnums_for_file
38
+
39
+ # Return an array of lines numbers that could be
40
+ # stopped at given a string.
41
+ def lnums_for_str(string, uniq=true)
42
+ lnums_for_iseq(RubyVM::InstructionSequence::compile(string),
43
+ uniq)
44
+ end
45
+ module_function :lnums_for_str
46
+
47
+ # Return an array of lines numbers that could be
48
+ # stopped at given a string array.
49
+ def lnums_for_str_array(string_array, newline='', uniq=true)
50
+ lnums_for_str(string_array.join(newline))
51
+ end
52
+ module_function :lnums_for_str_array
53
+ end
54
+
55
+ if __FILE__ == $0
56
+ SCRIPT_LINES__ = {} unless defined? SCRIPT_LINES__
57
+ # test_file = '../test/rcov-bug.rb'
58
+ test_file = '../test/lnum-data/begin1.rb'
59
+ if File.exists?(test_file)
60
+ puts TraceLineNumbers.lnums_for_file(test_file).inspect
61
+ load(test_file, 0) # for later
62
+ end
63
+ puts TraceLineNumbers.lnums_for_file(__FILE__).inspect
64
+ unless SCRIPT_LINES__.empty?
65
+ key = SCRIPT_LINES__.keys.first
66
+ puts key
67
+ puts SCRIPT_LINES__[key]
68
+ puts TraceLineNumbers.lnums_for_str_array(SCRIPT_LINES__[key]).inspect
69
+ end
70
+ end
@@ -0,0 +1,3 @@
1
+ # [ 3 ]
2
+ begin
3
+ end
@@ -0,0 +1,3 @@
1
+ # [ 2 ]
2
+ begin begin end end
3
+
@@ -0,0 +1,5 @@
1
+ # [ 4 ]
2
+ begin
3
+ begin
4
+ end
5
+ end
@@ -0,0 +1,7 @@
1
+ # [2, 3, 4, 6, 7]
2
+ if true
3
+ puts '3'
4
+ puts '4'
5
+ end
6
+ if true
7
+ end
@@ -0,0 +1,4 @@
1
+ # [0, 2, 3, 4]
2
+ def foo(&block)
3
+ end
4
+ foo{4}
@@ -0,0 +1,6 @@
1
+ # [ 2, 3, 4, 5, 6 ]
2
+ case 2
3
+ when 3
4
+ when 4
5
+ else
6
+ end
@@ -0,0 +1,5 @@
1
+ # [ 3, 4, 5 ]
2
+ case
3
+ when 3 != 3
4
+ when 4 != 4
5
+ end
@@ -0,0 +1,5 @@
1
+ # [2, 3, 4, 5]
2
+ case "2"
3
+ when Array
4
+ when Fixnum
5
+ end
@@ -0,0 +1,4 @@
1
+ # [2, 3, 4]
2
+ case "2"
3
+ when Array, Fixnum
4
+ end
@@ -0,0 +1,9 @@
1
+ # [ 2, 3, 4, 5, 6, 8, 9]
2
+ case '3'
3
+ when '4'
4
+ x = 5
5
+ when '6'
6
+ x = 7
7
+ else
8
+ x = 9
9
+ end
@@ -0,0 +1,5 @@
1
+ # [3, 4, 5]
2
+ class
3
+ A
4
+ class B ;
5
+ end end
@@ -0,0 +1,6 @@
1
+ # [ 6 ]
2
+
3
+ # space here and in next line
4
+
5
+
6
+
@@ -0,0 +1,9 @@
1
+ # [0, 2, 3, 4, 5, 6, 7, 8, 9]
2
+ def
3
+ a ; end
4
+ def b
5
+ end
6
+ def c(
7
+ a=7,
8
+ b=8)
9
+ end
@@ -0,0 +1,3 @@
1
+ # [ 2 ]
2
+ [2].each { }
3
+
@@ -0,0 +1,3 @@
1
+ # [ 3 ]
2
+ # POSTEXE
3
+ END { }
@@ -0,0 +1,4 @@
1
+ # [ 2, 3, 4 ]
2
+ for i in [2]
3
+ i
4
+ end
@@ -0,0 +1,4 @@
1
+ # [ 2 ]
2
+ x = true ? 1 : 2
3
+
4
+
@@ -0,0 +1,4 @@
1
+ # [ 2 ]
2
+ x = 2 if false
3
+
4
+
@@ -0,0 +1,9 @@
1
+ # [ 2, 3, 4, 5, 6]
2
+ lines = ''
3
+ opts = {:print_source => true}
4
+ if opts[:print_source]
5
+ puts 5
6
+ puts lines
7
+ end
8
+
9
+
@@ -0,0 +1,14 @@
1
+ # [ 6, 7, 8, 10 ]
2
+
3
+ # Running through Tracer will not give the line numbers in the same
4
+ # order. Also note 9 before 7. This is because in the parse tree
5
+ # != has been turned into == with the branches switched.
6
+ [true, false].each do |t|
7
+ if t != true
8
+ 8
9
+ else
10
+ 10
11
+ end
12
+ end
13
+
14
+
@@ -0,0 +1,7 @@
1
+ # [2, 3, 4]
2
+ x=2
3
+ x=3 if x=='a' or
4
+ false
5
+ # What's weird here is we get two stops on line 4 and both times x is
6
+ # 4. In Ruby 1.9 we don't get *any* line traces.
7
+
@@ -0,0 +1,4 @@
1
+ # [ 2 ]
2
+ x = 2 if x==3
3
+
4
+
@@ -0,0 +1,8 @@
1
+ # [ 2, 3, 4, 5, 6 ]
2
+ def f()
3
+ y=1
4
+ true
5
+ end
6
+ x = 2 if f()
7
+
8
+
@@ -0,0 +1,3 @@
1
+ # [ 3 ]
2
+ # MATCH -- FIXME we are not getting a match token.
3
+ /.*/
@@ -0,0 +1,5 @@
1
+ # [ 3, 5 ]
2
+ # MATCH3
3
+ 3 =~ /
4
+ x*
5
+ /
@@ -0,0 +1,6 @@
1
+ # [ 3, 4, 5, 6 ]
2
+ # MATCH3
3
+ y = 3
4
+ 4 =~ /
5
+ #{y}*
6
+ /
@@ -0,0 +1,6 @@
1
+ # [ 4, 6 ]
2
+ # not and lit
3
+ 3
4
+ not 4
5
+ not
6
+ 6
@@ -0,0 +1,130 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # begin require 'rubygems' rescue LoadError end
4
+ # require 'ruby-debug' ; Debugger.start
5
+
6
+ TEST_DIR = File.expand_path(File.dirname(__FILE__))
7
+ TOP_SRC_DIR = File.join(TEST_DIR, '..')
8
+ require File.join(TOP_SRC_DIR, 'lib', 'tracelines.rb')
9
+
10
+ def dump_file(file, opts)
11
+ puts file
12
+ begin
13
+ fp = File.open(file, 'r')
14
+ rescue Errno::ENOENT
15
+ puts "File #{file} is not readable."
16
+ return
17
+ end
18
+ lines = fp.read
19
+ if opts[:print_source]
20
+ puts '=' * 80
21
+ puts lines
22
+ end
23
+ if opts[:print_parse]
24
+ puts '=' * 80
25
+ cmd = "#{File.join(TEST_DIR, 'parse-show.rb')} #{file}"
26
+ system(cmd)
27
+ end
28
+ if opts[:print_trace]
29
+ require 'tracer'
30
+ puts '=' * 80
31
+ tracer = Tracer.new
32
+ tracer.add_filter lambda {|event, f, line, id, binding, klass|
33
+ __FILE__ != f && event == 'line'
34
+ }
35
+ tracer.on{load(file)}
36
+ end
37
+ expected_lnums = nil
38
+ if opts[:expect_line]
39
+ fp.rewind
40
+ first_line = fp.readline.chomp
41
+ expected_str = first_line[1..-1]
42
+ begin
43
+ expected_lnums = eval(expected_str, binding, __FILE__, __LINE__)
44
+ rescue SyntaxError
45
+ puts '=' * 80
46
+ puts "Failed reading expected values from #{file}"
47
+ end
48
+ end
49
+ fp.close()
50
+ got_lnums = TraceLineNumbers.lnums_for_str(lines)
51
+ if expected_lnums
52
+ puts "expecting: #{expected_lnums.inspect}"
53
+ puts '-' * 80
54
+ if expected_lnums
55
+ if got_lnums != expected_lnums
56
+ puts "mismatch: #{got_lnums.inspect}"
57
+ else
58
+ puts 'Got what was expected.'
59
+ end
60
+ else
61
+ puts got_lnums.inspect
62
+ end
63
+ else
64
+ puts got_lnums.inspect
65
+ end
66
+ end
67
+
68
+ require 'getoptlong'
69
+ program = File.basename($0)
70
+ opts = {
71
+ :print_source => true, # Print source file?
72
+ :print_trace => true, # Run Tracer over file?
73
+ :expect_line => true, # Source file has expected (correct) list of lines?
74
+ :print_parse => true, # Show ParseTree output?
75
+ }
76
+
77
+ getopts = GetoptLong.new(
78
+ [ '--expect', '-e', GetoptLong::NO_ARGUMENT ],
79
+ [ '--no-expect', '-E', GetoptLong::NO_ARGUMENT ],
80
+ [ '--help', '-h', GetoptLong::NO_ARGUMENT ],
81
+ [ '--parse', '-p', GetoptLong::NO_ARGUMENT ],
82
+ [ '--no-parse', '-P', GetoptLong::NO_ARGUMENT ],
83
+ [ '--source', '-s', GetoptLong::NO_ARGUMENT ],
84
+ [ '--no-source', '-S', GetoptLong::NO_ARGUMENT ],
85
+ [ '--trace', '-t', GetoptLong::NO_ARGUMENT ],
86
+ [ '--no-trace', '-T', GetoptLong::NO_ARGUMENT ])
87
+
88
+ getopts.each do |opt, arg|
89
+ case opt
90
+ when '--help'
91
+ puts "usage
92
+ Usage: #{$program} [options] file1 file2 ...
93
+
94
+ Diagnostic program to make see what TraceLineNumbers does and compare
95
+ against other output.
96
+
97
+ options:
98
+ -e --expect Read source file expected comment (default)
99
+ -E --no-expect Don't look for source file expected comment
100
+ -p --parse Show ParseTree Output (default)
101
+ -P --no-parse Don't show ParseTree output
102
+ -s --source Show source file (default)
103
+ -S --no-source Don't print source
104
+ -t --trace Show Tracer output (default)
105
+ -T --no-trace Don't show Tracer output
106
+ "
107
+ when '--expect'
108
+ opts[:expect_line] = true
109
+ when '--no-expect'
110
+ opts[:expect_line] = false
111
+ when '--parse'
112
+ opts[:print_parse] = true
113
+ when '--no-parse'
114
+ opts[:print_parse] = false
115
+ when '--source'
116
+ opts[:print_source] = true
117
+ when '--no-source'
118
+ opts[:print_source] = false
119
+ when '--trace'
120
+ opts[:print_trace] = true
121
+ when '--no-trace'
122
+ opts[:print_trace] = false
123
+ else
124
+ puts "Unknown and ignored option #{opt}"
125
+ end
126
+ end
127
+
128
+ ARGV.each do |file|
129
+ dump_file(file, opts)
130
+ end
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'pp'
4
+ begin require 'rubygems' rescue LoadError end
5
+ require 'parse_tree'
6
+
7
+ ARGV.push "-" if ARGV.empty?
8
+
9
+ parse_tree = ParseTree.new(true)
10
+
11
+ ARGV.each do |file|
12
+ ruby = file == "-" ? $stdin.read : File.read(file)
13
+ pp parse_tree.parse_tree_for_string(ruby, file).first
14
+ end
@@ -0,0 +1,10 @@
1
+ # [3, 5, 7, 10]
2
+ # Some rcov bugs.
3
+ z = "
4
+ Now is the time
5
+ "
6
+
7
+ z =~
8
+ /
9
+ 5
10
+ /ix
@@ -0,0 +1,2 @@
1
+ # This is a small test file.
2
+
@@ -0,0 +1,153 @@
1
+ #!/usr/bin/env ruby
2
+ require 'test/unit'
3
+ require 'fileutils'
4
+ require 'tempfile'
5
+ require 'set'
6
+
7
+ # require 'rubygems'
8
+ # require 'ruby-debug'; Debugger.start
9
+
10
+ # Test LineCache module
11
+ class TestLineCache < Test::Unit::TestCase
12
+ @@TEST_DIR = File.expand_path(File.dirname(__FILE__))
13
+ @@TOP_SRC_DIR = File.join(@@TEST_DIR, '..', 'lib')
14
+ require File.join(@@TOP_SRC_DIR, 'linecache.rb')
15
+
16
+ def setup
17
+ LineCache::clear_file_cache
18
+ end
19
+
20
+ def test_basic
21
+ fp = File.open(__FILE__, 'r')
22
+ compare_lines = fp.readlines()
23
+ fp.close
24
+
25
+ # Test getlines to read this file.
26
+ lines = LineCache::getlines(__FILE__)
27
+ assert_equal(compare_lines, lines,
28
+ 'We should get exactly the same lines as reading this file.')
29
+
30
+ # Test getline to read this file. The file should now be cached,
31
+ # so internally a different set of routines are used.
32
+ test_line = 1
33
+ line = LineCache::getline(__FILE__, test_line)
34
+ assert_equal(compare_lines[test_line-1], line,
35
+ 'We should get exactly the same line as reading this file.')
36
+
37
+ # Test getting the line via a relative file name
38
+ Dir.chdir(File.dirname(__FILE__)) do
39
+ short_file = File.basename(__FILE__)
40
+ test_line = 10
41
+ line = LineCache::getline(short_file, test_line)
42
+ assert_equal(compare_lines[test_line-1], line,
43
+ 'Short filename lookup should work')
44
+ end
45
+
46
+ # Write a temporary file; read contents, rewrite it and check that
47
+ # we get a change when calling getline.
48
+ tf = Tempfile.new("testing")
49
+ test_string = "Now is the time.\n"
50
+ tf.puts(test_string)
51
+ tf.close
52
+ line = LineCache::getline(tf.path, 1)
53
+ assert_equal(test_string, line,
54
+ "C'mon - a simple line test like this worked before.")
55
+ tf.open
56
+ test_string = "Now is another time.\n"
57
+ tf.puts(test_string)
58
+ tf.close
59
+ LineCache::checkcache
60
+ line = LineCache::getline(tf.path, 1)
61
+ assert_equal(test_string, line,
62
+ "checkcache should have reread the temporary file.")
63
+ FileUtils.rm tf.path
64
+
65
+ LineCache::update_cache(__FILE__)
66
+ LineCache::clear_file_cache
67
+ end
68
+
69
+ def test_cached
70
+ assert_equal(false, LineCache::cached?(__FILE__),
71
+ "file #{__FILE__} shouldn't be cached - just cleared cache.")
72
+ line = LineCache::getline(__FILE__, 1)
73
+ assert line
74
+ assert_equal(true, LineCache::cached?(__FILE__),
75
+ "file #{__FILE__} should now be cached")
76
+ assert_equal(false, LineCache::cached_script?('./short-file'),
77
+ "Should not find './short-file' in SCRIPT_LINES__")
78
+ assert_equal(true, 78 < LineCache.size(__FILE__))
79
+ Dir.chdir(File.dirname(__FILE__)) do
80
+ filename = './short-file'
81
+ load(filename, 0)
82
+ fullname = File.expand_path(filename)
83
+ assert_equal(true, LineCache::cached_script?(fullname),
84
+ "Should be able to find '#{filename}' in SCRIPT_LINES__")
85
+ end
86
+ end
87
+
88
+ def test_remap
89
+ LineCache::remap_file(__FILE__, 'another-name')
90
+ line1 = LineCache::getline('another-name', 1)
91
+ line2 = LineCache::getline(__FILE__, 1)
92
+ assert_equal(line1, line2, 'Both lines should be the same via remap_file')
93
+ end
94
+
95
+ def test_remap_lines
96
+ LineCache::remap_file_lines(__FILE__, 'test2', (10..11), 6)
97
+
98
+ line5 = LineCache::getline(__FILE__, 5)
99
+ LineCache::remap_file_lines(__FILE__, 'test2', 9, 5)
100
+ rline9 = LineCache::getline('test2', 9)
101
+ assert_equal(line5, rline9,
102
+ 'lines should be the same via remap_file_line - remap integer')
103
+
104
+ line6 = LineCache::getline(__FILE__, 6)
105
+ rline10 = LineCache::getline('test2', 10)
106
+ assert_equal(line6, rline10,
107
+ 'lines should be the same via remap_file_line - range')
108
+
109
+ line7 = LineCache::getline(__FILE__, 7)
110
+ rline11 = LineCache::getline('test2', 11)
111
+ assert_equal(line7, rline11,
112
+ 'lines should be the same via remap_file_line - range')
113
+
114
+ line8 = LineCache::getline(__FILE__, 8)
115
+ LineCache::remap_file_lines(__FILE__, nil, 20, 8)
116
+ rline20 = LineCache::getline(__FILE__, 20)
117
+ assert_equal(line8, rline20,
118
+ 'lines should be the same via remap_file_line - nil file')
119
+ end
120
+
121
+ def test_stat
122
+ assert_equal(nil, LineCache::stat(__FILE__),
123
+ "stat for #{__FILE__} shouldn't be nil - just cleared cache.")
124
+ line = LineCache::getline(__FILE__, 1)
125
+ assert line
126
+ assert(LineCache::stat(__FILE__),
127
+ "file #{__FILE__} should now have a stat")
128
+ end
129
+
130
+ def test_path
131
+ assert_equal(nil, LineCache::path(__FILE__),
132
+ "path for #{__FILE__} should be nil - just cleared cache.")
133
+ path = LineCache::cache(__FILE__)
134
+ assert path
135
+ assert_equal(path, LineCache::path(__FILE__),
136
+ "path of #{__FILE__} should be the same as we got before")
137
+ end
138
+
139
+ def test_trace_line_numbers
140
+ test_file = File.join(@@TEST_DIR, 'short-file')
141
+ assert_equal([2], LineCache::trace_line_numbers(test_file))
142
+ test_file = File.join(@@TEST_DIR, 'rcov-bug.rb')
143
+ assert_equal([3, 5, 7, 10], LineCache::trace_line_numbers(test_file))
144
+ end
145
+
146
+ def test_sha1
147
+ test_file = File.join(@@TEST_DIR, 'short-file')
148
+ LineCache::cache(test_file)
149
+ assert_equal('1134f95ea84a3dcc67d7d1bf41390ee1a03af6d2',
150
+ LineCache::sha1(test_file))
151
+ end
152
+
153
+ end