pry-doc 0.12.0 → 0.13.0pre1
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.
- checksums.yaml +4 -4
- data/Rakefile +1 -1
- data/lib/pry-doc/pry_ext/method_info.rb +2 -0
- data/lib/pry-doc/pry_ext/show_source_with_c_internals.rb +34 -0
- data/lib/pry-doc/pry_ext/show_source_with_c_internals/c_extractor.rb +195 -0
- data/lib/pry-doc/pry_ext/show_source_with_c_internals/c_file.rb +33 -0
- data/lib/pry-doc/version.rb +1 -1
- metadata +7 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 971c24126e91d04263621b3ad0493fb11b88ae8192d400a0e8ee8d70b68a4003
|
4
|
+
data.tar.gz: 6c7886db101a8dd7b3e342ebd650938648bbbe10be1315c398a2f0b6576a0538
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b170e72d7225b341aec06a40eb57eaf7c811ff6194a5a72fa55ce2cb65b73150ef2d9de1bc48e0c898bf306b5ea6d301d371147a054edcbbb4c8db6310db35f4
|
7
|
+
data.tar.gz: 5bc9c766dfe3d95ad39d0d1b21063a7344ed6e14b5dfec4deaa8f6529d6a44988719432483540252a835cece5bb43c381f9c2b9f50952aef00c30c5504d1ac1b
|
data/Rakefile
CHANGED
@@ -15,7 +15,7 @@ require "#{direc}/lib/#{PROJECT_NAME}/version"
|
|
15
15
|
desc "reinstall gem"
|
16
16
|
task :reinstall => :gems do
|
17
17
|
sh "gem uninstall pry-doc" rescue nil
|
18
|
-
sh "gem install #{direc}/pkg/pry-doc-#{PryDoc::VERSION}.gem"
|
18
|
+
sh "gem install #{direc}/pkg/pry-doc-#{PryDoc::VERSION}.gem --no-document"
|
19
19
|
end
|
20
20
|
|
21
21
|
desc "build all platform gems at once"
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require_relative "show_source_with_c_internals/c_extractor"
|
2
|
+
|
3
|
+
class ShowSourceWithCInternals < Pry::Command::ShowSource
|
4
|
+
def options(opt)
|
5
|
+
super(opt)
|
6
|
+
opt.on :c, "c-source", "Show source of a C symbol in MRI"
|
7
|
+
end
|
8
|
+
|
9
|
+
def extract_c_source
|
10
|
+
if opts.present?(:all)
|
11
|
+
result = CExtractor.new(opts).show_all_definitions(obj_name)
|
12
|
+
else
|
13
|
+
result = CExtractor.new(opts).show_first_definition(obj_name)
|
14
|
+
end
|
15
|
+
if result
|
16
|
+
_pry_.pager.page result
|
17
|
+
else
|
18
|
+
raise CommandError, no_definition_message
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def process
|
23
|
+
if opts.present?(:c)
|
24
|
+
extract_c_source
|
25
|
+
return
|
26
|
+
else
|
27
|
+
super
|
28
|
+
end
|
29
|
+
rescue Pry::CommandError
|
30
|
+
extract_c_source
|
31
|
+
end
|
32
|
+
|
33
|
+
Pry::Commands.add_command(ShowSourceWithCInternals)
|
34
|
+
end
|
@@ -0,0 +1,195 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require_relative 'c_file'
|
3
|
+
|
4
|
+
class CExtractor
|
5
|
+
include Pry::Helpers::Text
|
6
|
+
|
7
|
+
class << self
|
8
|
+
attr_accessor :file_cache
|
9
|
+
end
|
10
|
+
@file_cache = {}
|
11
|
+
|
12
|
+
attr_reader :opts
|
13
|
+
|
14
|
+
def initialize(opts)
|
15
|
+
@opts = opts
|
16
|
+
end
|
17
|
+
|
18
|
+
def balanced?(str)
|
19
|
+
tokens = CodeRay.scan(str, :c).tokens.each_slice(2).to_a
|
20
|
+
tokens.count { |v|
|
21
|
+
v.first =~ /{/ && v.last == :operator } == tokens.count { |v|
|
22
|
+
v.first =~ /}/ && v.last == :operator
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
def extract_struct(info)
|
27
|
+
source_file = source_from_file(info.file)
|
28
|
+
offset = 1
|
29
|
+
loop do
|
30
|
+
code = source_file[info.line, offset].join
|
31
|
+
break code if balanced?(code)
|
32
|
+
offset += 1
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def extract_typedef_struct(info)
|
37
|
+
source_file = source_from_file(info.file)
|
38
|
+
offset = 1
|
39
|
+
loop do
|
40
|
+
code = source_file[info.line - offset..info.line].join
|
41
|
+
break code if balanced?(code)
|
42
|
+
offset += 1
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def extract_macro(info)
|
47
|
+
source_file = source_from_file(info.file)
|
48
|
+
offset = 1
|
49
|
+
loop do
|
50
|
+
code = source_file[info.line, offset].join
|
51
|
+
break code unless source_file[info.line + offset - 1].strip.end_with?('\\')
|
52
|
+
offset += 1
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def extract_typedef_oneliner(info)
|
57
|
+
source_file = source_from_file(info.file)
|
58
|
+
return source_file[info.line]
|
59
|
+
end
|
60
|
+
|
61
|
+
def extract_function(info)
|
62
|
+
source_file = source_from_file(info.file)
|
63
|
+
offset = 1
|
64
|
+
|
65
|
+
if source_file[info.line] !~ /\w+\s+\w\(/ && source_file[info.line - 1].strip =~ /[\w\*]$/
|
66
|
+
start_line = info.line - 1
|
67
|
+
offset += 1
|
68
|
+
else
|
69
|
+
start_line = info.line
|
70
|
+
end
|
71
|
+
|
72
|
+
if !source_file[info.line].strip.end_with?("{")
|
73
|
+
offset += 1
|
74
|
+
end
|
75
|
+
|
76
|
+
loop do
|
77
|
+
code = source_file[start_line, offset].join
|
78
|
+
break code if balanced?(code)
|
79
|
+
offset += 1
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def file_cache
|
84
|
+
self.class.file_cache
|
85
|
+
end
|
86
|
+
|
87
|
+
def file_cache=(v)
|
88
|
+
self.class.file_cache = v
|
89
|
+
end
|
90
|
+
|
91
|
+
def full_path_for(file)
|
92
|
+
File.join(File.expand_path("~/.pry.d/ruby-#{ruby_version}"), file)
|
93
|
+
end
|
94
|
+
|
95
|
+
def source_from_file(file)
|
96
|
+
if file_cache.key?(file)
|
97
|
+
file_cache[file]
|
98
|
+
else
|
99
|
+
file_cache[file] = File.read(full_path_for(file)).lines
|
100
|
+
file_cache[file].unshift("\n")
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def use_line_numbers?
|
105
|
+
opts.present?(:b) || opts.present?(:l)
|
106
|
+
end
|
107
|
+
|
108
|
+
def show_all_definitions(x)
|
109
|
+
infos = self.class.symbol_map[x]
|
110
|
+
return unless infos
|
111
|
+
|
112
|
+
result = ""
|
113
|
+
infos.count.times do |index|
|
114
|
+
result << show_first_definition(x, index) << "\n"
|
115
|
+
end
|
116
|
+
result
|
117
|
+
end
|
118
|
+
|
119
|
+
def show_first_definition(x, index=nil)
|
120
|
+
infos = self.class.symbol_map[x]
|
121
|
+
return unless infos
|
122
|
+
|
123
|
+
count = infos.count
|
124
|
+
info = infos[index || 0]
|
125
|
+
code = if info.original_symbol.start_with?("#define")
|
126
|
+
extract_macro(info)
|
127
|
+
elsif info.original_symbol =~ /\s*struct\s*/ || info.original_symbol.start_with?("enum")
|
128
|
+
extract_struct(info)
|
129
|
+
elsif info.original_symbol.start_with?("}")
|
130
|
+
extract_typedef_struct(info)
|
131
|
+
elsif info.original_symbol =~/^typedef.*;$/
|
132
|
+
extract_typedef_oneliner(info)
|
133
|
+
else
|
134
|
+
extract_function(info)
|
135
|
+
end
|
136
|
+
|
137
|
+
h = "\n#{bold('From: ')}#{info.file} @ line #{info.line}:\n"
|
138
|
+
h << "#{bold('Number of implementations:')} #{count}\n" unless index
|
139
|
+
h << "#{bold('Number of lines: ')} #{code.lines.count}\n\n"
|
140
|
+
h << Pry::Code.new(code, start_line_for(info.line), :c).
|
141
|
+
with_line_numbers(use_line_numbers?).highlighted
|
142
|
+
end
|
143
|
+
|
144
|
+
def start_line_for(line)
|
145
|
+
if opts.present?(:'base-one')
|
146
|
+
1
|
147
|
+
else
|
148
|
+
line || 1
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def self.install_and_setup_ruby_source
|
153
|
+
puts "Downloading and setting up Ruby #{ruby_version} source..."
|
154
|
+
FileUtils.mkdir_p(File.expand_path("~/.pry.d/"))
|
155
|
+
FileUtils.cd(File.expand_path("~/.pry.d")) do
|
156
|
+
%x{ curl -L https://github.com/ruby/ruby/archive/v#{ruby_version}.tar.gz | tar xzvf - > /dev/null 2>&1 }
|
157
|
+
end
|
158
|
+
|
159
|
+
FileUtils.cd(File.expand_path("~/.pry.d/ruby-#{ruby_version}")) do
|
160
|
+
puts "Generating tagfile!"
|
161
|
+
%x{ find . -type f -name "*.[chy]" | etags - -o tags }
|
162
|
+
end
|
163
|
+
puts "...Finished!"
|
164
|
+
end
|
165
|
+
|
166
|
+
def self.tagfile
|
167
|
+
if !File.directory?(File.expand_path("~/.pry.d/ruby-#{ruby_version}"))
|
168
|
+
install_and_setup_ruby_source
|
169
|
+
end
|
170
|
+
|
171
|
+
@tagfile ||= File.read(File.expand_path("~/.pry.d/ruby-#{ruby_version}/tags"))
|
172
|
+
end
|
173
|
+
|
174
|
+
def ruby_version
|
175
|
+
self.class.ruby_version
|
176
|
+
end
|
177
|
+
|
178
|
+
# normalized
|
179
|
+
def self.ruby_version
|
180
|
+
RUBY_VERSION.tr(".", "_")
|
181
|
+
end
|
182
|
+
|
183
|
+
def self.parse_tagfile
|
184
|
+
@c_files ||= tagfile.split("\f\n")[1..-1].map do |v|
|
185
|
+
CFile.from_str(v)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
def self.symbol_map
|
190
|
+
parse_tagfile
|
191
|
+
@symbol_map ||= @c_files.each_with_object({}) do |v, h|
|
192
|
+
h.merge!(v.symbols) { |k, old_val, new_val| old_val + new_val }
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
class CFile
|
2
|
+
SourceLocation = Struct.new(:file, :line, :original_symbol)
|
3
|
+
|
4
|
+
attr_accessor :symbols, :file_name
|
5
|
+
|
6
|
+
def self.from_str(str)
|
7
|
+
new(str).tap(&:process_symbols)
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize(str)
|
11
|
+
@lines = str.lines
|
12
|
+
@file_name = @lines.shift.split(",").first
|
13
|
+
end
|
14
|
+
|
15
|
+
def process_symbols
|
16
|
+
@symbols = @lines.map do |v|
|
17
|
+
symbol, line_number = v.split("\x7f")
|
18
|
+
[cleanup_symbol(symbol),
|
19
|
+
[SourceLocation.new(@file_name, cleanup_linenumber(line_number), symbol.strip)]]
|
20
|
+
end.to_h
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def cleanup_symbol(symbol)
|
26
|
+
symbol = symbol.split.last
|
27
|
+
symbol.chomp("(").chomp("*").chomp(";")
|
28
|
+
end
|
29
|
+
|
30
|
+
def cleanup_linenumber(line_number)
|
31
|
+
line_number.split.first.to_i
|
32
|
+
end
|
33
|
+
end
|
data/lib/pry-doc/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pry-doc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.13.0pre1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Mair (banisterfiend)
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-02-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: yard
|
@@ -128,6 +128,9 @@ files:
|
|
128
128
|
- lib/pry-doc/docs/25/objects/root.dat
|
129
129
|
- lib/pry-doc/docs/25/proxy_types
|
130
130
|
- lib/pry-doc/pry_ext/method_info.rb
|
131
|
+
- lib/pry-doc/pry_ext/show_source_with_c_internals.rb
|
132
|
+
- lib/pry-doc/pry_ext/show_source_with_c_internals/c_extractor.rb
|
133
|
+
- lib/pry-doc/pry_ext/show_source_with_c_internals/c_file.rb
|
131
134
|
- lib/pry-doc/version.rb
|
132
135
|
- pry-doc.gemspec
|
133
136
|
- spec/gem_with_cext/gems/ext/extconf.rb
|
@@ -151,9 +154,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
151
154
|
version: '2.0'
|
152
155
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
153
156
|
requirements:
|
154
|
-
- - "
|
157
|
+
- - ">"
|
155
158
|
- !ruby/object:Gem::Version
|
156
|
-
version:
|
159
|
+
version: 1.3.1
|
157
160
|
requirements: []
|
158
161
|
rubyforge_project:
|
159
162
|
rubygems_version: 2.7.3
|