pry-doc 0.12.0 → 0.13.0pre1

Sign up to get free protection for your applications and to get access to all the features.
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