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