peeky 0.0.39 → 0.0.45
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/.rubocop.yml +1 -1
- data/Guardfile +1 -1
- data/README.md +4 -0
- data/Rakefile +15 -0
- data/lib/peeky/class_info.rb +73 -20
- data/lib/peeky/method_info.rb +20 -21
- data/lib/peeky/predicates/attr_reader_predicate.rb +6 -1
- data/lib/peeky/renderer/class_debug_render.rb +16 -10
- data/lib/peeky/renderer/class_interface_render.rb +72 -37
- data/lib/peeky/renderer/class_interface_yard_render.rb +86 -52
- data/lib/peeky/renderer/method_call_minimum_params_render.rb +6 -6
- data/lib/peeky/version.rb +1 -1
- data/lib/peeky.rb +7 -0
- data/peeky.gemspec +4 -0
- metadata +3 -3
- data/lib/peeky/example/yard_sample.rb +0 -140
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b59687793d9f01e4a7c6f0db2e1fdd8e20b614446815c82f13decabf5661704b
|
4
|
+
data.tar.gz: d49b1a2a72414094caff610f371fa242688e78b07f91edb38d7565a9aa5f650c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 15d8633c3f3e3e917161c4b6acaa40e16cf3a6c58fb4cbeb2c4bfb00c8f3f168e81092aa8ecd397fedcba521a4b9a58a4101e9fa70598b20e1c623f4f27c3636
|
7
|
+
data.tar.gz: cf82156956b67d6b90f467ce816418cd9a56fcc05e0f98bd5c96e29fe448fde7727420489114651fdaab89c27a004759bf8508d79c4f15fafdfbebe1e59b3421
|
data/.rubocop.yml
CHANGED
data/Guardfile
CHANGED
@@ -23,7 +23,7 @@ group :green_pass_then_cop, halt_on_fail: true do
|
|
23
23
|
watch(%r{^lib/peeky/commands/(.+)\.rb$}) { |m| "spec/unit/commands/#{m[1]}_spec.rb" }
|
24
24
|
end
|
25
25
|
|
26
|
-
guard :rubocop, all_on_start: false, cli: ['--format', 'clang'] do
|
26
|
+
guard :rubocop, all_on_start: false, cli: ['--format', 'clang', '-a'] do
|
27
27
|
watch(%r{.+\.rb$})
|
28
28
|
watch(%r{(?:.+/)?\.rubocop(?:_todo)?\.yml$}) { |m| File.dirname(m[0]) }
|
29
29
|
end
|
data/README.md
CHANGED
@@ -4,6 +4,10 @@
|
|
4
4
|
|
5
5
|
When using the source code for this gem, start by running `bin/setup` to install locally or `bundle install`
|
6
6
|
|
7
|
+
## TODO
|
8
|
+
|
9
|
+
@klueless-io - look at [show-source](https://stackoverflow.com/questions/13012109/get-class-location-from-class-object)
|
10
|
+
|
7
11
|
## Installation
|
8
12
|
|
9
13
|
Add this line to your application's Gemfile:
|
data/Rakefile
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
GEM_NAME = 'peeky'
|
4
|
+
|
3
5
|
require 'bundler/gem_tasks'
|
4
6
|
require 'rspec/core/rake_task'
|
5
7
|
|
@@ -14,3 +16,16 @@ Rake::ExtensionTask.new('peeky') do |ext|
|
|
14
16
|
end
|
15
17
|
|
16
18
|
task default: %i[clobber compile spec]
|
19
|
+
|
20
|
+
desc 'Publish the gem to RubyGems.org'
|
21
|
+
task :publish do
|
22
|
+
system 'gem build'
|
23
|
+
system "gem push #{GEM_NAME}-#{Peeky::VERSION}.gem"
|
24
|
+
end
|
25
|
+
|
26
|
+
desc 'Remove old *.gem files'
|
27
|
+
task :clean do
|
28
|
+
system 'rm *.gem'
|
29
|
+
end
|
30
|
+
|
31
|
+
task default: %i[clobber compile spec]
|
data/lib/peeky/class_info.rb
CHANGED
@@ -26,16 +26,23 @@ module Peeky
|
|
26
26
|
else
|
27
27
|
result.push kv('# of instance methods', '')
|
28
28
|
end
|
29
|
-
if defined?(@
|
29
|
+
if defined?(@signatures)
|
30
30
|
result.push kv('# of accessors', accessors.length)
|
31
31
|
result.push kv('# of readers', readers.length)
|
32
32
|
result.push kv('# of writers', writers.length)
|
33
|
-
result.push kv('# of methods',
|
33
|
+
result.push kv('# of methods', all_methods.length)
|
34
|
+
result.push kv('# of methods - public', public_methods.length)
|
35
|
+
result.push kv('# of methods - private', private_methods.length)
|
36
|
+
result.push kv('# of class methods', class_methods.length)
|
37
|
+
|
34
38
|
else
|
35
|
-
result.push
|
36
|
-
result.push kv('# of
|
37
|
-
result.push kv('# of
|
38
|
-
result.push kv('# of
|
39
|
+
result.push 'Not Loaded'
|
40
|
+
# result.push kv('# of accessors', '')
|
41
|
+
# result.push kv('# of readers', '')
|
42
|
+
# result.push kv('# of writers', '')
|
43
|
+
# result.push kv('# of methods', '')
|
44
|
+
# result.push kv('# of methods - public', '')
|
45
|
+
# result.push kv('# of methods - private', '')
|
39
46
|
end
|
40
47
|
result.join("\n")
|
41
48
|
end
|
@@ -49,8 +56,6 @@ module Peeky
|
|
49
56
|
# At times during debug or other edge cases, it may be useful to
|
50
57
|
# pre-load this information early.
|
51
58
|
def load
|
52
|
-
ruby_instance_methods
|
53
|
-
ruby_instance_method_names
|
54
59
|
signatures
|
55
60
|
end
|
56
61
|
|
@@ -61,19 +66,19 @@ module Peeky
|
|
61
66
|
|
62
67
|
# Class name
|
63
68
|
def class_name
|
64
|
-
@
|
69
|
+
@class_name ||= class_full_name.to_s.gsub(/^.*::/, '')
|
65
70
|
# instance.class.name.split('::').last
|
66
71
|
end
|
67
72
|
|
68
73
|
# Module name
|
69
74
|
def module_name
|
70
|
-
@
|
75
|
+
@module_name ||= class_full_name.to_s.gsub(/(.*)::.*/, '\1')
|
71
76
|
end
|
72
77
|
|
73
78
|
# Get a list of :attr_accessor on the class
|
74
79
|
# @return [Array<AttrInfo>] list of AttrInfo where type is :attr_accessor
|
75
80
|
def accessors
|
76
|
-
@
|
81
|
+
@accessors ||= attribute_infos.select { |attribute_info| attribute_info.type == :attr_accessor }
|
77
82
|
end
|
78
83
|
|
79
84
|
# Get a list of :attr_accessors ordered the way they are in the source code
|
@@ -86,7 +91,7 @@ module Peeky
|
|
86
91
|
|
87
92
|
# Attribute infos
|
88
93
|
def attribute_infos
|
89
|
-
@
|
94
|
+
@attribute_infos ||= begin
|
90
95
|
grouped_method_infos = signatures.select { |signature| signature.readable? || signature.writable? }.group_by(&:clean_name)
|
91
96
|
|
92
97
|
grouped_method_infos.keys.map { |key| AttrInfo.create(*grouped_method_infos[key]) }
|
@@ -102,8 +107,26 @@ module Peeky
|
|
102
107
|
|
103
108
|
# Get a list methods
|
104
109
|
# @return [Array<MethodInfo>] list of MethodInfo where type is :method
|
105
|
-
def
|
106
|
-
@
|
110
|
+
def all_methods
|
111
|
+
@all_methods ||= signatures.select { |signature| signature.implementation_type == :method }
|
112
|
+
end
|
113
|
+
|
114
|
+
# Get a list of private methods
|
115
|
+
# @return [Array<MethodInfo>] list of MethodInfo where type is :method
|
116
|
+
def private_methods
|
117
|
+
@private_methods ||= signatures.select { |signature| signature.implementation_type == :method && signature.access_control == :private }
|
118
|
+
end
|
119
|
+
|
120
|
+
# Get a list of public methods
|
121
|
+
# @return [Array<MethodInfo>] list of MethodInfo where type is :method
|
122
|
+
def public_methods
|
123
|
+
@public_methods ||= signatures.select { |signature| signature.implementation_type == :method && signature.access_control == :public }
|
124
|
+
end
|
125
|
+
|
126
|
+
# Get a list of class methods
|
127
|
+
# @return [Array<MethodInfo>] list of MethodInfo where type is :method
|
128
|
+
def class_methods
|
129
|
+
@class_methods ||= signatures.select { |signature| signature.implementation_type == :class_method }
|
107
130
|
end
|
108
131
|
|
109
132
|
# Get a list methods ordered the way they are in the source code
|
@@ -111,7 +134,7 @@ module Peeky
|
|
111
134
|
def methods_source_order
|
112
135
|
# TODO: This feature is required
|
113
136
|
# May be best to have a sort object that can be created for each type of ordering that is needed
|
114
|
-
|
137
|
+
all_methods
|
115
138
|
end
|
116
139
|
|
117
140
|
# Reader by name
|
@@ -124,7 +147,7 @@ module Peeky
|
|
124
147
|
# Get a list of :attr_reader on the class
|
125
148
|
# @return [Array<AttrInfo>] list of AttrInfo where type is :attr_accessor
|
126
149
|
def readers
|
127
|
-
@
|
150
|
+
@readers ||= attribute_infos.select { |attribute_info| attribute_info.type == :attr_reader }
|
128
151
|
end
|
129
152
|
|
130
153
|
# Get a list of :attr_reader ordered the way they are in the source code
|
@@ -138,7 +161,7 @@ module Peeky
|
|
138
161
|
# Get a list of :attr_writer on the class
|
139
162
|
# @return [Array<AttrInfo>] list of AttrInfo where type is :attr_writer
|
140
163
|
def writers
|
141
|
-
@
|
164
|
+
@writers ||= attribute_infos.select { |attribute_info| attribute_info.type == :attr_writer }
|
142
165
|
end
|
143
166
|
|
144
167
|
# Get a list of :attr_writer ordered the way they are in the source code
|
@@ -161,7 +184,14 @@ module Peeky
|
|
161
184
|
# such as static, private vs public
|
162
185
|
# deep, deep_to_level, this_instance.
|
163
186
|
def signatures
|
164
|
-
@
|
187
|
+
return @signatures if defined? @signatures
|
188
|
+
|
189
|
+
@signatures = begin
|
190
|
+
instance_methods = ruby_instance_methods.map { |im| MethodInfo.new(im, @instance) }
|
191
|
+
private_methods = ruby_private_methods.map { |im| MethodInfo.new(im, @instance, access_control: :private) }
|
192
|
+
class_methods = ruby_class_methods.map { |im| MethodInfo.new(im, @instance, implementation_type: :class_method) }
|
193
|
+
instance_methods + private_methods + class_methods
|
194
|
+
end
|
165
195
|
end
|
166
196
|
|
167
197
|
# Signatures by clean name
|
@@ -187,13 +217,36 @@ module Peeky
|
|
187
217
|
"#{key.to_s.ljust(25)}: #{value}"
|
188
218
|
end
|
189
219
|
|
220
|
+
def ruby_class_method_names
|
221
|
+
@ruby_class_method_names ||= instance.class.singleton_class.instance_methods(false).sort
|
222
|
+
end
|
223
|
+
|
190
224
|
def ruby_instance_method_names
|
191
|
-
@
|
225
|
+
@ruby_instance_method_names ||= instance.class.instance_methods(false).sort
|
226
|
+
end
|
227
|
+
|
228
|
+
def ruby_private_method_names
|
229
|
+
@ruby_private_method_names ||= instance.private_methods(false).sort
|
230
|
+
end
|
231
|
+
|
232
|
+
def ruby_class_methods
|
233
|
+
@ruby_class_methods ||= ruby_class_method_names.map { |method_name| instance.class.method(method_name) }
|
234
|
+
rescue StandardError => e
|
235
|
+
# puts 'ruby_class_methods'
|
236
|
+
puts e
|
237
|
+
end
|
238
|
+
|
239
|
+
def ruby_private_methods
|
240
|
+
@ruby_private_methods ||= ruby_private_method_names.map { |method_name| instance.method(method_name) }
|
241
|
+
rescue StandardError => e
|
242
|
+
# puts 'ruby_private_methods'
|
243
|
+
puts e
|
192
244
|
end
|
193
245
|
|
194
246
|
def ruby_instance_methods
|
195
|
-
@
|
247
|
+
@ruby_instance_methods ||= ruby_instance_method_names.map { |method_name| instance.method(method_name) }
|
196
248
|
rescue StandardError => e
|
249
|
+
# puts 'ruby_instance_methods'
|
197
250
|
puts e
|
198
251
|
end
|
199
252
|
end
|
data/lib/peeky/method_info.rb
CHANGED
@@ -14,26 +14,29 @@ module Peeky
|
|
14
14
|
# MethodInfo delegates to the underlying ruby method object
|
15
15
|
attr_reader :focal_method
|
16
16
|
|
17
|
+
attr_reader :access_control
|
18
|
+
|
17
19
|
def_delegators :focal_method, :name, :receiver, :arity, :super_method
|
18
20
|
|
19
21
|
## Stage 2 is the method likely to be an attribute reader or writer
|
20
22
|
#
|
21
23
|
|
22
24
|
# Implementation type indicates the probable representation of this
|
23
|
-
# method in ruby, was it
|
25
|
+
# method in ruby, was it
|
26
|
+
# instance method `def method`
|
27
|
+
# instance method reader `attr_reader`
|
28
|
+
# instance method writer `attr_writer`
|
29
|
+
# class method `def self.method`
|
24
30
|
attr_reader :implementation_type
|
25
31
|
|
26
|
-
def initialize(method, target_instance)
|
32
|
+
def initialize(method, target_instance, implementation_type: :method, access_control: :public)
|
27
33
|
@focal_method = method
|
28
34
|
@target_instance = target_instance
|
35
|
+
@access_control = access_control
|
36
|
+
@implementation_type = implementation_type
|
29
37
|
@parameters = ParameterInfo.from_method(method)
|
30
|
-
# stage 1
|
31
|
-
# @implementation_type = :method
|
32
38
|
|
33
|
-
# stage 2
|
34
39
|
infer_implementation_type
|
35
|
-
|
36
|
-
# stage 3
|
37
40
|
infer_default_paramaters
|
38
41
|
end
|
39
42
|
|
@@ -52,20 +55,13 @@ module Peeky
|
|
52
55
|
end
|
53
56
|
end
|
54
57
|
|
55
|
-
# Infer implementation type [:method, :attr_reader or :attr_writer]
|
56
|
-
# rubocop:disable Lint/DuplicateBranch
|
58
|
+
# Infer implementation type [:class_method, :method, :attr_reader or :attr_writer]
|
57
59
|
def infer_implementation_type
|
58
|
-
@implementation_type
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
elsif match(Peeky::Predicates::AttrWriterPredicate)
|
63
|
-
:attr_writer
|
64
|
-
else
|
65
|
-
:method
|
66
|
-
end
|
60
|
+
return unless @implementation_type == :method
|
61
|
+
|
62
|
+
@implementation_type = :attr_reader if match(Peeky::Predicates::AttrReaderPredicate)
|
63
|
+
@implementation_type = :attr_writer if match(Peeky::Predicates::AttrWriterPredicate)
|
67
64
|
end
|
68
|
-
# rubocop:enable Lint/DuplicateBranch
|
69
65
|
|
70
66
|
# Get parameter by name
|
71
67
|
#
|
@@ -92,13 +88,16 @@ module Peeky
|
|
92
88
|
# The tests are now down to 5 seconds, but it highlights the cost of use
|
93
89
|
# TracePoint.
|
94
90
|
def infer_default_paramaters
|
95
|
-
|
91
|
+
class_name = @implementation_type == :class_method ? @target_instance.class.name : nil
|
92
|
+
minimalist_method = Peeky::Renderer::MethodCallMinimumParamsRender.new(self, class_name: class_name).render
|
96
93
|
|
97
94
|
return if minimalist_method.end_with?('=')
|
98
95
|
return unless optional?
|
99
96
|
|
100
97
|
tracer.enable do
|
101
|
-
|
98
|
+
# TODO: minimalist method should be able to handle class methods
|
99
|
+
@target_instance.instance_eval(minimalist_method) if @implementation_type == :method
|
100
|
+
@target_instance.class.instance_eval(minimalist_method) if @implementation_type == :class_method
|
102
101
|
rescue StandardError => e
|
103
102
|
# just print the error for now, we are only attempting to capture the
|
104
103
|
# first call, any errors inside the call cannot be dealt with and should
|
@@ -32,7 +32,12 @@ module Peeky
|
|
32
32
|
cloned = instance.clone
|
33
33
|
|
34
34
|
cloned.instance_eval(code)
|
35
|
-
|
35
|
+
begin
|
36
|
+
current_value = cloned.send(method_name)
|
37
|
+
rescue StandardError #=> exception
|
38
|
+
current_value = nil
|
39
|
+
end
|
40
|
+
|
36
41
|
current_value == new_value
|
37
42
|
end
|
38
43
|
|
@@ -24,13 +24,9 @@ module Peeky
|
|
24
24
|
output.push('')
|
25
25
|
end
|
26
26
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
output.push("-- Public Methods #{'-' * 82}")
|
31
|
-
output.push(*methods)
|
32
|
-
output.push('')
|
33
|
-
end
|
27
|
+
render_methods_with_heading(output, @class_info.public_methods, 'Public Methods')
|
28
|
+
render_methods_with_heading(output, @class_info.class_methods, 'Class Methods')
|
29
|
+
render_methods_with_heading(output, @class_info.private_methods, 'Private Methods')
|
34
30
|
|
35
31
|
output.pop if output.last == ''
|
36
32
|
|
@@ -70,10 +66,20 @@ module Peeky
|
|
70
66
|
@class_info.writers.map { |attr| kv('attr_writer', attr.name) }
|
71
67
|
end
|
72
68
|
|
73
|
-
def
|
74
|
-
|
69
|
+
def render_methods_with_heading(output, method_list, heading)
|
70
|
+
methods = render_methods(method_list)
|
71
|
+
|
72
|
+
return unless methods.length.positive?
|
73
|
+
|
74
|
+
output.push("-- #{heading} #{'-' * 82}")
|
75
|
+
output.push(*methods)
|
76
|
+
output.push('')
|
77
|
+
end
|
78
|
+
|
79
|
+
def render_methods(method_list)
|
80
|
+
method_list.flat_map do |method|
|
75
81
|
[
|
76
|
-
"#{method.name}
|
82
|
+
"[ #{method.name} ]",
|
77
83
|
*render_paramaters(method.parameters),
|
78
84
|
''
|
79
85
|
]
|
@@ -2,32 +2,44 @@
|
|
2
2
|
|
3
3
|
module Peeky
|
4
4
|
module Renderer
|
5
|
-
# Render: Class Interface
|
5
|
+
# Render: Class Interface Example
|
6
6
|
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
# attr_accessor :
|
7
|
+
# class ComplexClass
|
8
|
+
# attr_accessor :a_read_write1
|
9
|
+
# attr_accessor :a_read_write2
|
10
|
+
|
11
|
+
# attr_reader :b_another_reader
|
12
|
+
# attr_reader :b_reader
|
13
|
+
# attr_reader :looks_like_an_attr_reader
|
14
|
+
|
15
|
+
# attr_writer :c_another_writer
|
16
|
+
# attr_writer :c_writer
|
17
|
+
|
18
|
+
# def alpha_sort1; end
|
19
|
+
# def alpha_sort2; end
|
20
|
+
# def destructive!; end
|
21
|
+
# def do_something_method; end
|
22
|
+
# def method_01(aaa); end
|
23
|
+
# def method_02(aaa, bbb = 1); end
|
24
|
+
# def method_03(aaa, bbb = 1, ccc = 2); end
|
25
|
+
# def method_04(*aaa); end
|
26
|
+
# def method_05(aaa, bbb = 1, *ccc); end
|
27
|
+
# def method_06(**aaa); end
|
28
|
+
# def method_07(aaa, *bbb, ccc: 'string1', **ddd); end
|
29
|
+
# def method_08(aaa, *bbb, **ccc, &ddd); end
|
30
|
+
# def method_09(aaa:); end
|
31
|
+
# def method_10(aaa:, bbb: 1); end
|
32
|
+
# def method_with_every_type_of_paramater(aaa, bbb = 1, *ccc, ddd:, eee: 1, **fff, &ggg);end
|
33
|
+
# def questionable?; end
|
10
34
|
#
|
11
|
-
#
|
35
|
+
# class << self
|
36
|
+
# def klass_complex(aaa, bbb = nil, *ccc, ddd:, eee: , **fff, &ggg); end
|
37
|
+
# def klass_simple(first_param); end
|
38
|
+
# end
|
12
39
|
#
|
13
|
-
#
|
40
|
+
# private
|
14
41
|
#
|
15
|
-
# def
|
16
|
-
# def alpha_sort2; end
|
17
|
-
# def d; end
|
18
|
-
# def e(aaa); end
|
19
|
-
# def f(aaa, bbb = nil); end
|
20
|
-
# def g(aaa, bbb = nil, ccc = nil); end
|
21
|
-
# def h(*aaa); end
|
22
|
-
# def i(aaa, bbb, *ccc); end
|
23
|
-
# def j(**aaa); end
|
24
|
-
# def k(aaa, *bbb, **ccc); end
|
25
|
-
# def l(aaa, *bbb, **ccc, &ddd); end
|
26
|
-
# def m(aaa:); end
|
27
|
-
# def n(aaa:, bbb: nil); end
|
28
|
-
# def p?; end
|
29
|
-
# def q!; end
|
30
|
-
# def z(aaa, bbb = nil, *ccc, ddd:, eee: nil, **fff, &ggg); end
|
42
|
+
# def keep_me_private; end
|
31
43
|
# end
|
32
44
|
class ClassInterfaceRender
|
33
45
|
# ClassInfo with information about the class instance to be rendered.
|
@@ -40,19 +52,24 @@ module Peeky
|
|
40
52
|
# Render the class interface
|
41
53
|
def render
|
42
54
|
@indent = ''
|
43
|
-
output = []
|
44
|
-
output.push render_start
|
55
|
+
@output = []
|
56
|
+
@output.push render_start
|
45
57
|
@indent = ' '
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
58
|
+
|
59
|
+
render_accessors
|
60
|
+
render_readers
|
61
|
+
render_writers
|
62
|
+
|
63
|
+
render_methods(@class_info.public_methods)
|
64
|
+
render_class_methods(@class_info.class_methods)
|
65
|
+
render_private_methods(@class_info.private_methods)
|
66
|
+
|
67
|
+
@output.pop if @output.last == ''
|
51
68
|
|
52
69
|
@indent = ''
|
53
|
-
output.push render_end
|
70
|
+
@output.push render_end
|
54
71
|
|
55
|
-
output.join("\n")
|
72
|
+
@output.join("\n")
|
56
73
|
end
|
57
74
|
|
58
75
|
private
|
@@ -64,28 +81,46 @@ module Peeky
|
|
64
81
|
def render_accessors
|
65
82
|
result = @class_info.accessors.map { |attr| "#{@indent}attr_accessor :#{attr.name}" }
|
66
83
|
result.push '' unless result.length.zero?
|
67
|
-
result
|
84
|
+
@output += result
|
68
85
|
end
|
69
86
|
|
70
87
|
def render_readers
|
71
88
|
result = @class_info.readers.map { |attr| "#{@indent}attr_reader :#{attr.name}" }
|
72
89
|
result.push '' unless result.length.zero?
|
73
|
-
result
|
90
|
+
@output += result
|
74
91
|
end
|
75
92
|
|
76
93
|
def render_writers
|
77
94
|
result = @class_info.writers.map { |attr| "#{@indent}attr_writer :#{attr.name}" }
|
78
95
|
result.push '' unless result.length.zero?
|
79
|
-
result
|
96
|
+
@output += result
|
80
97
|
end
|
81
98
|
|
82
|
-
def render_methods
|
83
|
-
result =
|
99
|
+
def render_methods(method_list)
|
100
|
+
result = method_list.map do |method_signature|
|
84
101
|
render_signature = Peeky::Renderer::MethodSignatureRender.new(method_signature)
|
85
102
|
"#{@indent}#{render_signature.render}"
|
86
103
|
end
|
87
104
|
result.push '' unless result.length.zero?
|
88
|
-
result
|
105
|
+
@output += result
|
106
|
+
end
|
107
|
+
|
108
|
+
def render_class_methods(methods)
|
109
|
+
return if methods.length.zero?
|
110
|
+
|
111
|
+
@output += ["#{@indent}class << self"]
|
112
|
+
@indent += ' '
|
113
|
+
@output += render_methods(methods)
|
114
|
+
@indent.delete_suffix!(' ')
|
115
|
+
@output.pop if @output.last == ''
|
116
|
+
@output += ["#{@indent}end", '']
|
117
|
+
end
|
118
|
+
|
119
|
+
def render_private_methods(methods)
|
120
|
+
return if methods.length.zero?
|
121
|
+
|
122
|
+
@output += ["#{@indent}private", '']
|
123
|
+
@output += render_methods(methods)
|
89
124
|
end
|
90
125
|
|
91
126
|
def render_end
|
@@ -33,26 +33,33 @@ module Peeky
|
|
33
33
|
|
34
34
|
# Render the class interface with YARD documentation
|
35
35
|
def render
|
36
|
-
output = []
|
37
|
-
|
36
|
+
@output = []
|
37
|
+
|
38
|
+
render_start
|
38
39
|
@indent += ' '
|
39
|
-
|
40
|
-
|
40
|
+
|
41
|
+
render_accessors
|
42
|
+
render_readers
|
43
|
+
render_writers
|
44
|
+
|
45
|
+
render_public_methods
|
46
|
+
render_class_methods
|
47
|
+
render_private_methods
|
48
|
+
|
49
|
+
@output.pop if @output.last == ''
|
41
50
|
|
42
51
|
@indent = @indent[0..-3]
|
43
52
|
|
44
|
-
output.push render_end
|
53
|
+
@output.push render_end
|
45
54
|
|
46
|
-
output.join("\n")
|
55
|
+
@output.join("\n")
|
47
56
|
end
|
48
57
|
|
49
58
|
private
|
50
59
|
|
51
60
|
def render_start
|
52
|
-
|
53
|
-
|
54
|
-
"#{@indent}class #{@class_info.class_name}"
|
55
|
-
]
|
61
|
+
@output.push "#{@indent}# #{@class_info.class_name.titleize.humanize}"
|
62
|
+
@output.push "#{@indent}class #{@class_info.class_name}"
|
56
63
|
end
|
57
64
|
|
58
65
|
def render_accessors
|
@@ -63,7 +70,7 @@ module Peeky
|
|
63
70
|
result.push "#{@indent}attr_accessor :#{attr.name}"
|
64
71
|
end
|
65
72
|
result.push '' unless result.length.zero?
|
66
|
-
result
|
73
|
+
@output += result
|
67
74
|
end
|
68
75
|
|
69
76
|
def render_readers
|
@@ -74,7 +81,7 @@ module Peeky
|
|
74
81
|
result.push "#{@indent}attr_reader :#{attr.name}"
|
75
82
|
end
|
76
83
|
result.push '' unless result.length.zero?
|
77
|
-
result
|
84
|
+
@output += result
|
78
85
|
end
|
79
86
|
|
80
87
|
def render_writers
|
@@ -85,54 +92,81 @@ module Peeky
|
|
85
92
|
result.push "#{@indent}attr_writer :#{attr.name}"
|
86
93
|
end
|
87
94
|
result.push '' unless result.length.zero?
|
88
|
-
result
|
95
|
+
@output += result
|
89
96
|
end
|
90
97
|
|
91
|
-
|
92
|
-
def render_methods
|
98
|
+
def render_public_methods
|
93
99
|
result = []
|
94
|
-
class_info.
|
95
|
-
result
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
when :param_optional
|
115
|
-
result.push "#{@indent}# @param #{parameter.name} [#{parameter.default_value_type}] #{parameter.name} is optional, defaults to #{parameter.wrap_default_value('nil')}"
|
116
|
-
# result.push "#{@indent}# @param #{parameter.name} [#{default_param_type}] #{parameter.name.to_s.humanize.downcase} (optional)"
|
117
|
-
else
|
118
|
-
result.push "#{@indent}# @param #{parameter.name} [#{default_param_type}] #{parameter.name.to_s.humanize.downcase}"
|
119
|
-
end
|
120
|
-
end
|
100
|
+
class_info.public_methods.map.with_index do |method_signature, index|
|
101
|
+
render_method(result, method_signature, index)
|
102
|
+
end
|
103
|
+
result.push '' unless result.length.zero?
|
104
|
+
@output += result
|
105
|
+
end
|
106
|
+
|
107
|
+
def render_class_methods
|
108
|
+
return if class_info.class_methods.length.zero?
|
109
|
+
|
110
|
+
result = ["#{@indent}# Class methods", "#{@indent}class << self"]
|
111
|
+
@indent += ' '
|
112
|
+
class_info.class_methods.map.with_index do |method_signature, index|
|
113
|
+
render_method(result, method_signature, index)
|
114
|
+
end
|
115
|
+
@indent.delete_suffix!(' ')
|
116
|
+
result.push "#{@indent}end"
|
117
|
+
|
118
|
+
@output += result
|
119
|
+
end
|
121
120
|
|
122
|
-
|
123
|
-
|
124
|
-
|
121
|
+
def render_private_methods
|
122
|
+
result = []
|
123
|
+
class_info.private_methods.map.with_index do |method_signature, index|
|
124
|
+
result.push "\n#{indent}private\n" if index.zero?
|
125
|
+
render_method(result, method_signature, index)
|
126
|
+
end
|
127
|
+
@output += result
|
128
|
+
end
|
129
|
+
|
130
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
|
131
|
+
def render_method(result, method_signature, index)
|
132
|
+
result.push '' if index.positive?
|
133
|
+
result.push "#{@indent}# #{method_signature.name.to_s.humanize}"
|
134
|
+
|
135
|
+
method_signature.parameters.each_with_index do |parameter, param_index|
|
136
|
+
result.push "#{@indent}#" if param_index.zero?
|
137
|
+
|
138
|
+
case parameter.type
|
139
|
+
when :splat
|
140
|
+
result.push "#{@indent}# @param #{parameter.name} [Array<#{default_splat_param_type}>] *#{parameter.name} - list of #{parameter.name.to_s.humanize.downcase}"
|
141
|
+
when :double_splat
|
142
|
+
result.push "#{@indent}# @param #{parameter.name} [<key: value>...] **#{parameter.name} - list of key/values"
|
143
|
+
when :block
|
144
|
+
result.push "#{@indent}# @param #{parameter.name} [Block] &#{parameter.name}"
|
145
|
+
when :key_required
|
146
|
+
result.push "#{@indent}# @param #{parameter.name} [#{default_param_type}] #{parameter.name}: <value for #{parameter.name.to_s.humanize.downcase}> (required)"
|
147
|
+
when :key_optional
|
148
|
+
result.push "#{@indent}# @param #{parameter.name} [#{parameter.default_value_type}] #{parameter.name}: is optional, defaults to #{parameter.wrap_default_value('nil')}"
|
149
|
+
when :param_required
|
150
|
+
result.push "#{@indent}# @param #{parameter.name} [#{default_param_type}] #{parameter.name.to_s.humanize.downcase} (required)"
|
151
|
+
when :param_optional
|
152
|
+
result.push "#{@indent}# @param #{parameter.name} [#{parameter.default_value_type}] #{parameter.name} is optional, defaults to #{parameter.wrap_default_value('nil')}"
|
153
|
+
# result.push "#{@indent}# @param #{parameter.name} [#{default_param_type}] #{parameter.name.to_s.humanize.downcase} (optional)"
|
154
|
+
else
|
155
|
+
result.push "#{@indent}# @param #{parameter.name} [#{default_param_type}] #{parameter.name.to_s.humanize.downcase}"
|
125
156
|
end
|
157
|
+
end
|
126
158
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
result.push render_signature.render
|
159
|
+
if method_signature.name.to_s.end_with?('?')
|
160
|
+
result.push ''
|
161
|
+
result.push "#{@indent}# @return [Boolean] true when #{method_signature.name.to_s.humanize.downcase}"
|
131
162
|
end
|
132
|
-
|
133
|
-
|
163
|
+
|
164
|
+
render_signature = Peeky::Renderer::MethodSignatureRender.new(method_signature)
|
165
|
+
render_signature.indent = @indent
|
166
|
+
render_signature.style = :default
|
167
|
+
result.push render_signature.render
|
134
168
|
end
|
135
|
-
# rubocop:enable Metrics/AbcSize, Metrics/
|
169
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
|
136
170
|
|
137
171
|
def render_end
|
138
172
|
"#{@indent}end"
|
@@ -13,7 +13,8 @@ module Peeky
|
|
13
13
|
|
14
14
|
def initialize(method_signature, **opts)
|
15
15
|
# instance_name = opts[:instance_name] || 'instance'
|
16
|
-
@instance_name
|
16
|
+
@instance_name = opts[:instance_name]
|
17
|
+
@class_name = opts[:class_name]
|
17
18
|
@method_signature = method_signature
|
18
19
|
end
|
19
20
|
|
@@ -29,11 +30,10 @@ module Peeky
|
|
29
30
|
|
30
31
|
params = minimal_call_parameters.length.zero? ? '' : "(#{minimal_call_parameters})"
|
31
32
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
end
|
33
|
+
return "#{@instance_name}.#{name}#{params}" unless @instance_name.nil?
|
34
|
+
return "#{@class_name}.#{name}#{params}" unless @class_name.nil?
|
35
|
+
|
36
|
+
"#{name}#{params}"
|
37
37
|
end
|
38
38
|
end
|
39
39
|
end
|
data/lib/peeky/version.rb
CHANGED
data/lib/peeky.rb
CHANGED
@@ -23,3 +23,10 @@ module Peeky
|
|
23
23
|
class Error < StandardError; end
|
24
24
|
# Your code goes here...
|
25
25
|
end
|
26
|
+
|
27
|
+
if ENV['KLUE_DEBUG']&.to_s&.downcase == 'true'
|
28
|
+
namespace = 'Peeky::Version'
|
29
|
+
file_path = $LOADED_FEATURES.find { |f| f.include?('peeky/version') }
|
30
|
+
version = Peeky::VERSION.ljust(9)
|
31
|
+
puts "#{namespace.ljust(35)} : #{version.ljust(9)} : #{file_path}"
|
32
|
+
end
|
data/peeky.gemspec
CHANGED
@@ -19,6 +19,10 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.metadata['homepage_uri'] = spec.homepage
|
20
20
|
spec.metadata['source_code_uri'] = 'https://github.com/klueless-io/peeky'
|
21
21
|
spec.metadata['changelog_uri'] = 'https://github.com/klueless-io/peeky/commits/master'
|
22
|
+
# Go to: https://rubydoc.info/
|
23
|
+
# Click Add Project:
|
24
|
+
# git@github.com:klueless-io/peeky
|
25
|
+
spec.metadata['documentation_uri'] = 'https://rubydoc.info/github/klueless-io/peeky/master'
|
22
26
|
|
23
27
|
# Specify which files should be added to the gem when it is released.
|
24
28
|
# The `git ls-files -z` loads the RubyGem files that have been added into git.
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: peeky
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.45
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Cruwys
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-10-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -59,7 +59,6 @@ files:
|
|
59
59
|
- lib/peeky/api.rb
|
60
60
|
- lib/peeky/attr_info.rb
|
61
61
|
- lib/peeky/class_info.rb
|
62
|
-
- lib/peeky/example/yard_sample.rb
|
63
62
|
- lib/peeky/method_info.rb
|
64
63
|
- lib/peeky/parameter_info.rb
|
65
64
|
- lib/peeky/predicates/attr_reader_predicate.rb
|
@@ -79,6 +78,7 @@ metadata:
|
|
79
78
|
homepage_uri: http://appydave.com/gems/peeky
|
80
79
|
source_code_uri: https://github.com/klueless-io/peeky
|
81
80
|
changelog_uri: https://github.com/klueless-io/peeky/commits/master
|
81
|
+
documentation_uri: https://rubydoc.info/github/klueless-io/peeky/master
|
82
82
|
post_install_message:
|
83
83
|
rdoc_options:
|
84
84
|
- "--title"
|
@@ -1,140 +0,0 @@
|
|
1
|
-
module Peeky
|
2
|
-
module Example
|
3
|
-
# Yard sample
|
4
|
-
class YardSample
|
5
|
-
# A read write1
|
6
|
-
attr_accessor :a_read_write1
|
7
|
-
|
8
|
-
# A read write2
|
9
|
-
attr_accessor :a_read_write2
|
10
|
-
|
11
|
-
# A read write3
|
12
|
-
attr_accessor :a_read_write3
|
13
|
-
|
14
|
-
# B reader1
|
15
|
-
attr_reader :b_reader1
|
16
|
-
|
17
|
-
# B reader2
|
18
|
-
attr_reader :b_reader2
|
19
|
-
|
20
|
-
# E looks like an attr reader
|
21
|
-
attr_reader :e_looks_like_an_attr_reader
|
22
|
-
|
23
|
-
# C writer1
|
24
|
-
attr_writer :c_writer1
|
25
|
-
|
26
|
-
# C writer2
|
27
|
-
attr_writer :c_writer2
|
28
|
-
|
29
|
-
# Alpha sort1
|
30
|
-
def alpha_sort1
|
31
|
-
end
|
32
|
-
|
33
|
-
# Alpha sort2
|
34
|
-
def alpha_sort2
|
35
|
-
end
|
36
|
-
|
37
|
-
# D do something method
|
38
|
-
def d_do_something_method
|
39
|
-
end
|
40
|
-
|
41
|
-
# E method with required param
|
42
|
-
#
|
43
|
-
# @param first_name [String] first name (required)
|
44
|
-
def e_method_with_required_param(first_name)
|
45
|
-
end
|
46
|
-
|
47
|
-
# F method with required param and optional param
|
48
|
-
#
|
49
|
-
# @param first_name [String] first name (required)
|
50
|
-
# @param last_name [String] last_name is optional, defaults to ''
|
51
|
-
def f_method_with_required_param_and_optional_param(first_name, last_name = '')
|
52
|
-
end
|
53
|
-
|
54
|
-
# G method with required param and two optional params
|
55
|
-
#
|
56
|
-
# @param first_name [String] first name (required)
|
57
|
-
# @param last_name [String] last_name is optional, defaults to ''
|
58
|
-
# @param age [Integer] age is optional, defaults to 21
|
59
|
-
def g_method_with_required_param_and_two_optional_params(first_name, last_name = '', age = 21)
|
60
|
-
end
|
61
|
-
|
62
|
-
# H list of optional parameters
|
63
|
-
#
|
64
|
-
# @param command_args [Array<Object>] *command_args - list of command args
|
65
|
-
def h_list_of_optional_parameters(*command_args)
|
66
|
-
end
|
67
|
-
|
68
|
-
# I method with two required params and list of optional params
|
69
|
-
#
|
70
|
-
# @param first_name [String] first name (required)
|
71
|
-
# @param last_name [String] last name (required)
|
72
|
-
# @param alias_names [Array<Object>] *alias_names - list of alias names
|
73
|
-
def i_method_with_two_required_params_and_list_of_optional_params(first_name, last_name, *alias_names)
|
74
|
-
end
|
75
|
-
|
76
|
-
# J method with list of named arguments
|
77
|
-
#
|
78
|
-
# @param options [<key: value>...] **options - list of key/values
|
79
|
-
def j_method_with_list_of_named_arguments(**options)
|
80
|
-
end
|
81
|
-
|
82
|
-
# K method with block
|
83
|
-
#
|
84
|
-
# @param code_block [Block] &code_block
|
85
|
-
def k_method_with_block(&code_block)
|
86
|
-
end
|
87
|
-
|
88
|
-
# L method with key value param required
|
89
|
-
#
|
90
|
-
# @param name [String] name: <value for name> (required)
|
91
|
-
def l_method_with_key_value_param_required(name:)
|
92
|
-
end
|
93
|
-
|
94
|
-
# N method with key value param required and optional key value
|
95
|
-
#
|
96
|
-
# @param last_name [String] last_name: <value for last name> (required)
|
97
|
-
# @param salutation [String] salutation: is optional, defaults to 'Mr'
|
98
|
-
def n_method_with_key_value_param_required_and_optional_key_value(last_name:, salutation: 'Mr')
|
99
|
-
end
|
100
|
-
|
101
|
-
# P available?
|
102
|
-
|
103
|
-
# @return [Boolean] true when p available?
|
104
|
-
def p_available?
|
105
|
-
end
|
106
|
-
|
107
|
-
# Q danger will robinson!
|
108
|
-
def q_danger_will_robinson!
|
109
|
-
end
|
110
|
-
|
111
|
-
# Z complex
|
112
|
-
#
|
113
|
-
# @param aaa [String] aaa (required)
|
114
|
-
# @param bbb [Integer] bbb is optional, defaults to 1
|
115
|
-
# @param ccc [Array<Object>] *ccc - list of ccc
|
116
|
-
# @param ddd [String] ddd: <value for ddd> (required)
|
117
|
-
# @param eee [Integer] eee: is optional, defaults to 1
|
118
|
-
# @param fff [<key: value>...] **fff - list of key/values
|
119
|
-
# @param ggg [Block] &ggg
|
120
|
-
def z_complex(aaa, bbb = 1, *ccc, ddd:, eee: 1, **fff, &ggg)
|
121
|
-
end
|
122
|
-
|
123
|
-
# Z optional styles
|
124
|
-
#
|
125
|
-
# @param aaa [String] aaa (required)
|
126
|
-
# @param bbb [Integer] bbb is optional, defaults to 123
|
127
|
-
# @param ccc [String] ccc is optional, defaults to 'abc'
|
128
|
-
# @param ddd [TrueClass] ddd is optional, defaults to true
|
129
|
-
# @param eee [FalseClass] eee is optional, defaults to false
|
130
|
-
# @param fff [Object] fff is optional, defaults to nil
|
131
|
-
# @param ggg [Integer] ggg: is optional, defaults to 123
|
132
|
-
# @param hhh [String] hhh: is optional, defaults to 'xyz'
|
133
|
-
# @param iii [TrueClass] iii: is optional, defaults to true
|
134
|
-
# @param jjj [FalseClass] jjj: is optional, defaults to false
|
135
|
-
# @param kkk [Object] kkk: is optional, defaults to nil
|
136
|
-
def z_optional_styles(aaa, bbb = 123, ccc = 'abc', ddd = true, eee = false, fff = nil, ggg: 123, hhh: 'xyz', iii: true, jjj: false, kkk: )
|
137
|
-
end
|
138
|
-
end
|
139
|
-
end
|
140
|
-
end
|