peeky 0.0.40 → 0.0.47

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: '08eb3e66afafe6b6af1896abb030457b6bd417ddaed97311f174b30458805146'
4
- data.tar.gz: 587f9afee745e58ee2783aa80d23c482a096ad8f96b8d50cbe9a1683b5f23188
3
+ metadata.gz: bd2714ca018026119c093e7920cd6de4202f809add8780595dc1bc2d77fa4c33
4
+ data.tar.gz: dfd1dfc025023e32c2b2892b3880c2be63a54bbc347d269cee0e19533a72fa4b
5
5
  SHA512:
6
- metadata.gz: 2cf0854c592886fc801068f7bf3bb310bcbb8db1b343be375e1b4ad82ab574fba783697bdce642358747784a247ba4b1ee49885a6737662866568f1e550e71f8
7
- data.tar.gz: 6a77ec688a91339da22a3f7c7c58e2ea7b9f8f7c99ec19e1998673484c4e197a2291d207c34fc42ab64d288055cc3b50e827a32659a39c1ee48aa7b758cb0e9c
6
+ metadata.gz: 359c0c49597ed2154c73d6db25c5a0b6c6d33dc1f6a3f464d594558ef31143a278f1428c58f0319c1205b8bbe6eb703300ff17daa9f1d89df8613e041d08a80a
7
+ data.tar.gz: c1b259ebbd335fdb71e907dd9bef8c8fb1dd63bbfd1ca767be83e7a2879aebb7485d3ec18b4cc067e074ebf4a4407ccefdaf33670fe4231b09b8cee4fbbae6e0
data/.rubocop.yml CHANGED
@@ -5,7 +5,7 @@ AllCops:
5
5
  NewCops: enable
6
6
  Exclude:
7
7
  - "_/**/*"
8
- - "lib/peeky/example/yard_sample.rb"
8
+ - "spec/sample/**/*"
9
9
 
10
10
  # My Preferences - Start
11
11
  Metrics/ClassLength:
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:
@@ -17,6 +17,20 @@ module Peeky
17
17
  @instance = instance
18
18
  end
19
19
 
20
+ def to_h
21
+ {
22
+ class_name: class_name,
23
+ module_name: module_name,
24
+ class_full_name: class_full_name,
25
+ attr_accessor: accessors.map(&:name),
26
+ attr_reader: readers.map(&:name),
27
+ attr_writer: writers.map(&:name),
28
+ klass: methods_to_h(class_methods),
29
+ instance_public: methods_to_h(public_methods),
30
+ instance_private: methods_to_h(private_methods)
31
+ }
32
+ end
33
+
20
34
  # rubocop:disable Metrics/AbcSize
21
35
  def to_s
22
36
  result = []
@@ -26,16 +40,23 @@ module Peeky
26
40
  else
27
41
  result.push kv('# of instance methods', '')
28
42
  end
29
- if defined?(@_signatures)
43
+ if defined?(@signatures)
30
44
  result.push kv('# of accessors', accessors.length)
31
45
  result.push kv('# of readers', readers.length)
32
46
  result.push kv('# of writers', writers.length)
33
- result.push kv('# of methods', methods.length)
47
+ result.push kv('# of methods', all_methods.length)
48
+ result.push kv('# of methods - public', public_methods.length)
49
+ result.push kv('# of methods - private', private_methods.length)
50
+ result.push kv('# of class methods', class_methods.length)
51
+
34
52
  else
35
- result.push kv('# of accessors', '')
36
- result.push kv('# of readers', '')
37
- result.push kv('# of writers', '')
38
- result.push kv('# of methods', '')
53
+ result.push 'Not Loaded'
54
+ # result.push kv('# of accessors', '')
55
+ # result.push kv('# of readers', '')
56
+ # result.push kv('# of writers', '')
57
+ # result.push kv('# of methods', '')
58
+ # result.push kv('# of methods - public', '')
59
+ # result.push kv('# of methods - private', '')
39
60
  end
40
61
  result.join("\n")
41
62
  end
@@ -49,8 +70,6 @@ module Peeky
49
70
  # At times during debug or other edge cases, it may be useful to
50
71
  # pre-load this information early.
51
72
  def load
52
- ruby_instance_methods
53
- ruby_instance_method_names
54
73
  signatures
55
74
  end
56
75
 
@@ -61,19 +80,19 @@ module Peeky
61
80
 
62
81
  # Class name
63
82
  def class_name
64
- @_class_name ||= class_full_name.to_s.gsub(/^.*::/, '')
83
+ @class_name ||= class_full_name.to_s.gsub(/^.*::/, '')
65
84
  # instance.class.name.split('::').last
66
85
  end
67
86
 
68
87
  # Module name
69
88
  def module_name
70
- @_module_name ||= class_full_name.to_s.gsub(/(.*)::.*/, '\1')
89
+ @module_name ||= class_full_name.to_s.gsub(/(.*)::.*/, '\1')
71
90
  end
72
91
 
73
92
  # Get a list of :attr_accessor on the class
74
93
  # @return [Array<AttrInfo>] list of AttrInfo where type is :attr_accessor
75
94
  def accessors
76
- @_accessors ||= attribute_infos.select { |attribute_info| attribute_info.type == :attr_accessor }
95
+ @accessors ||= attribute_infos.select { |attribute_info| attribute_info.type == :attr_accessor }
77
96
  end
78
97
 
79
98
  # Get a list of :attr_accessors ordered the way they are in the source code
@@ -86,7 +105,7 @@ module Peeky
86
105
 
87
106
  # Attribute infos
88
107
  def attribute_infos
89
- @_attribute_infos ||= begin
108
+ @attribute_infos ||= begin
90
109
  grouped_method_infos = signatures.select { |signature| signature.readable? || signature.writable? }.group_by(&:clean_name)
91
110
 
92
111
  grouped_method_infos.keys.map { |key| AttrInfo.create(*grouped_method_infos[key]) }
@@ -102,8 +121,26 @@ module Peeky
102
121
 
103
122
  # Get a list methods
104
123
  # @return [Array<MethodInfo>] list of MethodInfo where type is :method
105
- def methods
106
- @_methods ||= signatures.select { |signature| signature.implementation_type == :method }
124
+ def all_methods
125
+ @all_methods ||= signatures.select { |signature| signature.implementation_type == :method }
126
+ end
127
+
128
+ # Get a list of private methods
129
+ # @return [Array<MethodInfo>] list of MethodInfo where type is :method
130
+ def private_methods
131
+ @private_methods ||= signatures.select { |signature| signature.implementation_type == :method && signature.access_control == :private }
132
+ end
133
+
134
+ # Get a list of public methods
135
+ # @return [Array<MethodInfo>] list of MethodInfo where type is :method
136
+ def public_methods
137
+ @public_methods ||= signatures.select { |signature| signature.implementation_type == :method && signature.access_control == :public }
138
+ end
139
+
140
+ # Get a list of class methods
141
+ # @return [Array<MethodInfo>] list of MethodInfo where type is :method
142
+ def class_methods
143
+ @class_methods ||= signatures.select { |signature| signature.implementation_type == :class_method }
107
144
  end
108
145
 
109
146
  # Get a list methods ordered the way they are in the source code
@@ -111,7 +148,7 @@ module Peeky
111
148
  def methods_source_order
112
149
  # TODO: This feature is required
113
150
  # May be best to have a sort object that can be created for each type of ordering that is needed
114
- methods
151
+ all_methods
115
152
  end
116
153
 
117
154
  # Reader by name
@@ -124,7 +161,7 @@ module Peeky
124
161
  # Get a list of :attr_reader on the class
125
162
  # @return [Array<AttrInfo>] list of AttrInfo where type is :attr_accessor
126
163
  def readers
127
- @_readers ||= attribute_infos.select { |attribute_info| attribute_info.type == :attr_reader }
164
+ @readers ||= attribute_infos.select { |attribute_info| attribute_info.type == :attr_reader }
128
165
  end
129
166
 
130
167
  # Get a list of :attr_reader ordered the way they are in the source code
@@ -138,7 +175,7 @@ module Peeky
138
175
  # Get a list of :attr_writer on the class
139
176
  # @return [Array<AttrInfo>] list of AttrInfo where type is :attr_writer
140
177
  def writers
141
- @_writers ||= attribute_infos.select { |attribute_info| attribute_info.type == :attr_writer }
178
+ @writers ||= attribute_infos.select { |attribute_info| attribute_info.type == :attr_writer }
142
179
  end
143
180
 
144
181
  # Get a list of :attr_writer ordered the way they are in the source code
@@ -161,7 +198,14 @@ module Peeky
161
198
  # such as static, private vs public
162
199
  # deep, deep_to_level, this_instance.
163
200
  def signatures
164
- @_signatures ||= ruby_instance_methods.map { |im| MethodInfo.new(im, @instance) }
201
+ return @signatures if defined? @signatures
202
+
203
+ @signatures = begin
204
+ instance_methods = ruby_instance_methods.map { |im| MethodInfo.new(im, @instance) }
205
+ private_methods = ruby_private_methods.map { |im| MethodInfo.new(im, @instance, access_control: :private) }
206
+ class_methods = ruby_class_methods.map { |im| MethodInfo.new(im, @instance, implementation_type: :class_method) }
207
+ instance_methods + private_methods + class_methods
208
+ end
165
209
  end
166
210
 
167
211
  # Signatures by clean name
@@ -187,14 +231,52 @@ module Peeky
187
231
  "#{key.to_s.ljust(25)}: #{value}"
188
232
  end
189
233
 
234
+ def ruby_class_method_names
235
+ @ruby_class_method_names ||= instance.class.methods(false).sort # singleton_class.instance_methods(false).sort
236
+ end
237
+
190
238
  def ruby_instance_method_names
191
- @_ruby_instance_method_names ||= instance.class.instance_methods(false).sort
239
+ @ruby_instance_method_names ||= instance.class.instance_methods(false).sort
240
+ end
241
+
242
+ def ruby_private_method_names
243
+ @ruby_private_method_names ||= instance.private_methods(false).sort
244
+ end
245
+
246
+ def ruby_class_methods
247
+ @ruby_class_methods ||= ruby_class_method_names.map { |method_name| instance.class.method(method_name) }
248
+ rescue StandardError => e
249
+ # puts 'ruby_class_methods'
250
+ puts e
251
+ end
252
+
253
+ def ruby_private_methods
254
+ @ruby_private_methods ||= ruby_private_method_names.map { |method_name| instance.method(method_name) }
255
+ rescue StandardError => e
256
+ # puts 'ruby_private_methods'
257
+ puts e
192
258
  end
193
259
 
194
260
  def ruby_instance_methods
195
- @_ruby_instance_methods ||= ruby_instance_method_names.map { |method_name| instance.method(method_name) }
261
+ @ruby_instance_methods ||= ruby_instance_method_names.map { |method_name| instance.method(method_name) }
196
262
  rescue StandardError => e
263
+ # puts 'ruby_instance_methods'
197
264
  puts e
198
265
  end
266
+
267
+ def methods_to_h(methods)
268
+ methods.map do |m|
269
+ {
270
+ name: m.name,
271
+ paramaters: m.parameters.map do |p|
272
+ {
273
+ name: p.name,
274
+ type: p.type,
275
+ default_value: p.default_value
276
+ }
277
+ end
278
+ }
279
+ end
280
+ end
199
281
  end
200
282
  end
@@ -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 `def method` or `attr_reader` / `attr_writer`
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 = if @target_instance.nil?
59
- :method
60
- elsif match(Peeky::Predicates::AttrReaderPredicate)
61
- :attr_reader
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
- minimalist_method = Peeky::Renderer::MethodCallMinimumParamsRender.new(self).render
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
- @target_instance.instance_eval(minimalist_method)
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
- current_value = cloned.send(method_name)
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
- methods = render_methods
28
-
29
- if methods.length.positive?
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 render_methods
74
- @class_info.methods.flat_map do |method|
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
- # Example output:
8
- # class SampleClassClassInterfaceRender
9
- # attr_accessor :a
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
- # attr_reader :b
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
- # attr_writer :c
40
+ # private
14
41
  #
15
- # def alpha_sort1; end
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
- output += render_accessors
47
- output += render_readers
48
- output += render_writers
49
- output += render_methods
50
- output.pop if output.last == ''
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 = @class_info.methods.map do |method_signature|
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
- output.push render_start
36
+ @output = []
37
+
38
+ render_start
38
39
  @indent += ' '
39
- output += (render_accessors + render_readers + render_writers + render_methods)
40
- output.pop if output.last == ''
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
- "#{@indent}# #{@class_info.class_name.titleize.humanize}",
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
- # rubocop:disable Metrics/AbcSize, Metrics/BlockLength, Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity, Metrics/MethodLength
92
- def render_methods
98
+ def render_public_methods
93
99
  result = []
94
- class_info.methods.map.with_index do |method_signature, index|
95
- result.push '' if index.positive?
96
- result.push "#{@indent}# #{method_signature.name.to_s.humanize}"
97
-
98
- method_signature.parameters.each_with_index do |parameter, param_index|
99
- result.push "#{@indent}#" if param_index.zero?
100
-
101
- case parameter.type
102
- when :splat
103
- result.push "#{@indent}# @param #{parameter.name} [Array<#{default_splat_param_type}>] *#{parameter.name} - list of #{parameter.name.to_s.humanize.downcase}"
104
- when :double_splat
105
- result.push "#{@indent}# @param #{parameter.name} [<key: value>...] **#{parameter.name} - list of key/values"
106
- when :block
107
- result.push "#{@indent}# @param #{parameter.name} [Block] &#{parameter.name}"
108
- when :key_required
109
- result.push "#{@indent}# @param #{parameter.name} [#{default_param_type}] #{parameter.name}: <value for #{parameter.name.to_s.humanize.downcase}> (required)"
110
- when :key_optional
111
- result.push "#{@indent}# @param #{parameter.name} [#{parameter.default_value_type}] #{parameter.name}: is optional, defaults to #{parameter.wrap_default_value('nil')}"
112
- when :param_required
113
- result.push "#{@indent}# @param #{parameter.name} [#{default_param_type}] #{parameter.name.to_s.humanize.downcase} (required)"
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
- if method_signature.name.to_s.end_with?('?')
123
- result.push ''
124
- result.push "#{@indent}# @return [Boolean] true when #{method_signature.name.to_s.humanize.downcase}"
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
- render_signature = Peeky::Renderer::MethodSignatureRender.new(method_signature)
128
- render_signature.indent = @indent
129
- render_signature.style = :default
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
- result.push '' unless result.length.zero?
133
- result
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/BlockLength, Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity, Metrics/MethodLength
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 = opts[: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
- if @instance_name.nil?
33
- "#{name}#{params}"
34
- else
35
- "#{@instance_name}.#{name}#{params}"
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Peeky
4
- VERSION = '0.0.40'
4
+ VERSION = '0.0.47'
5
5
  end
data/lib/peeky.rb CHANGED
@@ -24,4 +24,9 @@ module Peeky
24
24
  # Your code goes here...
25
25
  end
26
26
 
27
- puts "Peeky::Version: #{Peeky::VERSION}" if ENV['KLUE_DEBUG']&.to_s&.downcase == 'true'
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
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.40
4
+ version: 0.0.47
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-04-01 00:00:00.000000000 Z
11
+ date: 2021-10-04 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
@@ -1,146 +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
- # Jin
83
- #
84
- # @param aaa [String] aaa (required)
85
- def jin(aaa)
86
- end
87
-
88
- # K method with block
89
- #
90
- # @param code_block [Block] &code_block
91
- def k_method_with_block(&code_block)
92
- end
93
-
94
- # L method with key value param required
95
- #
96
- # @param name [String] name: <value for name> (required)
97
- def l_method_with_key_value_param_required(name:)
98
- end
99
-
100
- # N method with key value param required and optional key value
101
- #
102
- # @param last_name [String] last_name: <value for last name> (required)
103
- # @param salutation [String] salutation: is optional, defaults to 'Mr'
104
- def n_method_with_key_value_param_required_and_optional_key_value(last_name:, salutation: 'Mr')
105
- end
106
-
107
- # P available?
108
-
109
- # @return [Boolean] true when p available?
110
- def p_available?
111
- end
112
-
113
- # Q danger will robinson!
114
- def q_danger_will_robinson!
115
- end
116
-
117
- # Z complex
118
- #
119
- # @param aaa [String] aaa (required)
120
- # @param bbb [Integer] bbb is optional, defaults to 1
121
- # @param ccc [Array<Object>] *ccc - list of ccc
122
- # @param ddd [String] ddd: <value for ddd> (required)
123
- # @param eee [Integer] eee: is optional, defaults to 1
124
- # @param fff [<key: value>...] **fff - list of key/values
125
- # @param ggg [Block] &ggg
126
- def z_complex(aaa, bbb = 1, *ccc, ddd:, eee: 1, **fff, &ggg)
127
- end
128
-
129
- # Z optional styles
130
- #
131
- # @param aaa [String] aaa (required)
132
- # @param bbb [Integer] bbb is optional, defaults to 123
133
- # @param ccc [String] ccc is optional, defaults to 'abc'
134
- # @param ddd [TrueClass] ddd is optional, defaults to true
135
- # @param eee [FalseClass] eee is optional, defaults to false
136
- # @param fff [Object] fff is optional, defaults to nil
137
- # @param ggg [Integer] ggg: is optional, defaults to 123
138
- # @param hhh [String] hhh: is optional, defaults to 'xyz'
139
- # @param iii [TrueClass] iii: is optional, defaults to true
140
- # @param jjj [FalseClass] jjj: is optional, defaults to false
141
- # @param kkk [Object] kkk: is optional, defaults to nil
142
- def z_optional_styles(aaa, bbb = 123, ccc = 'abc', ddd = true, eee = false, fff = nil, ggg: 123, hhh: 'xyz', iii: true, jjj: false, kkk: )
143
- end
144
- end
145
- end
146
- end