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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3dddcde8d4130ee9d1cf1e2b11342be1e5aac4708c8c8cab9b89d3c667ad34f0
4
- data.tar.gz: 7f9c47861ba003f7f67d5882da498a6c5c6d13476e8b09260103799fe3461264
3
+ metadata.gz: 971c24126e91d04263621b3ad0493fb11b88ae8192d400a0e8ee8d70b68a4003
4
+ data.tar.gz: 6c7886db101a8dd7b3e342ebd650938648bbbe10be1315c398a2f0b6576a0538
5
5
  SHA512:
6
- metadata.gz: f848ad58137f8732722081f92d3d68ed32054813ff7a1a2eec2acf5dd62c2a7b80e55820684b8d10ce2471fa90a32556f8bd24ab446570056b084e3a0b867e76
7
- data.tar.gz: dd80231ecf32471e38a3780cc2efc2e6f843d86da9bdebfc0458868c04c3df23a7a1de3c56cae89d892a4fe6998e5679fa36531514a92723b60124df7aef0b10
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"
@@ -1,3 +1,5 @@
1
+ require_relative "show_source_with_c_internals"
2
+
1
3
  class Pry
2
4
  module MethodInfo
3
5
  class << self
@@ -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
@@ -1,3 +1,3 @@
1
1
  module PryDoc
2
- VERSION = '0.12.0'
2
+ VERSION = '0.13.0pre1'
3
3
  end
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.12.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-01-21 00:00:00.000000000 Z
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: '0'
159
+ version: 1.3.1
157
160
  requirements: []
158
161
  rubyforge_project:
159
162
  rubygems_version: 2.7.3