peeky 0.0.27 → 0.0.40
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/.github/workflows/ruby.yml +2 -3
- data/.rubocop.yml +8 -3
- data/CODE_OF_CONDUCT.md +1 -1
- data/Gemfile +15 -9
- data/Guardfile +4 -4
- data/README.md +96 -5
- data/Rakefile +15 -0
- data/{README-stories.md → STORIES.md} +11 -15
- data/USAGE.md +438 -0
- data/USAGE2.md +5 -0
- data/lib/peeky.rb +3 -0
- data/lib/peeky/api.rb +19 -2
- data/lib/peeky/attr_info.rb +4 -0
- data/lib/peeky/class_info.rb +40 -36
- data/lib/peeky/example/yard_sample.rb +33 -10
- data/lib/peeky/method_info.rb +106 -27
- data/lib/peeky/parameter_info.rb +102 -26
- data/lib/peeky/renderer/class_debug_render.rb +95 -0
- data/lib/peeky/renderer/class_interface_yard_render.rb +8 -8
- data/lib/peeky/renderer/method_call_minimum_params_render.rb +7 -3
- data/lib/peeky/version.rb +1 -1
- data/peeky.gemspec +11 -17
- metadata +19 -12
data/USAGE2.md
ADDED
data/lib/peeky.rb
CHANGED
@@ -12,6 +12,7 @@ require 'peeky/parameter_info'
|
|
12
12
|
require 'peeky/predicates/attr_reader_predicate'
|
13
13
|
require 'peeky/predicates/attr_writer_predicate'
|
14
14
|
|
15
|
+
require 'peeky/renderer/class_debug_render'
|
15
16
|
require 'peeky/renderer/class_interface_render'
|
16
17
|
require 'peeky/renderer/class_interface_yard_render'
|
17
18
|
require 'peeky/renderer/method_call_minimum_params_render'
|
@@ -22,3 +23,5 @@ module Peeky
|
|
22
23
|
class Error < StandardError; end
|
23
24
|
# Your code goes here...
|
24
25
|
end
|
26
|
+
|
27
|
+
puts "Peeky::Version: #{Peeky::VERSION}" if ENV['KLUE_DEBUG']&.to_s&.downcase == 'true'
|
data/lib/peeky/api.rb
CHANGED
@@ -16,11 +16,24 @@ module Peeky
|
|
16
16
|
# ClassInfo stores information about the instance of a
|
17
17
|
# class that is passed in including methods, attr_accessors
|
18
18
|
# attr_readers and attr_writers.
|
19
|
-
|
20
|
-
|
19
|
+
#
|
20
|
+
# @param instance [Object] instance of class to gather information about (required)
|
21
|
+
# @param lazy [TrueClass] lazy load method and parameter information, laze: is optional, defaults to true
|
22
|
+
def build_class_info(instance, lazy: true)
|
23
|
+
ci = Peeky::ClassInfo.new(instance)
|
24
|
+
ci.load unless lazy
|
25
|
+
ci
|
21
26
|
end
|
22
27
|
|
23
28
|
# Render a class using a predefined class renderer
|
29
|
+
#
|
30
|
+
# ^1: One of class_info and instance must supplied, they are mutually
|
31
|
+
# exclusive to each other.
|
32
|
+
#
|
33
|
+
# @param render_key [Symbol] class render key (required)
|
34
|
+
# @param class_info [Object] class_info: is optional^1, defaults to nil
|
35
|
+
# @param instance [Object] instance: is optional^1, defaults to nil
|
36
|
+
# @param _opts [<key: value>...] **_opts - list of key/values that can help configure render
|
24
37
|
def render_class(render_key, class_info: nil, instance: nil, **_opts)
|
25
38
|
raise 'Call render_class with class_info OR instance.' if class_info.nil? && instance.nil?
|
26
39
|
raise 'Call render_class with class_info OR instance, these parameters are mutually exclusive' if !class_info.nil? && !instance.nil?
|
@@ -35,6 +48,7 @@ module Peeky
|
|
35
48
|
# Get a method renderer by :key
|
36
49
|
#
|
37
50
|
# TODO: Refactor to a configurable system
|
51
|
+
# @param key [String] key is a shortcut to a specific Peeky::Render that handles method_info (required)
|
38
52
|
def method_renderer(key)
|
39
53
|
case key
|
40
54
|
when :signature
|
@@ -51,8 +65,11 @@ module Peeky
|
|
51
65
|
# Get a class renderer by :key
|
52
66
|
#
|
53
67
|
# TODO: Refactor to a configurable system
|
68
|
+
# @param key [String] key is a shortcut to a specific Peeky::Renderer that handles class_info (required)
|
54
69
|
def class_renderer(key)
|
55
70
|
case key
|
71
|
+
when :class_debug
|
72
|
+
Peeky::Renderer::ClassDebugRender
|
56
73
|
when :class_interface
|
57
74
|
Peeky::Renderer::ClassInterfaceRender
|
58
75
|
when :class_interface_yard
|
data/lib/peeky/attr_info.rb
CHANGED
@@ -6,7 +6,9 @@ module Peeky
|
|
6
6
|
# Attr Info is a container that holds read, write or read/write
|
7
7
|
# attributes in the form of MethodInfo objects
|
8
8
|
class AttrInfo
|
9
|
+
# reader stores a MethodInfo for a matching reader, nil if readable style method_info not found
|
9
10
|
attr_reader :reader
|
11
|
+
# writer stores a MethodInfo for a matching writer, nil if writable style method_info not found
|
10
12
|
attr_reader :writer
|
11
13
|
|
12
14
|
def initialize(reader: nil, writer: nil)
|
@@ -16,6 +18,7 @@ module Peeky
|
|
16
18
|
@writer = writer
|
17
19
|
end
|
18
20
|
|
21
|
+
# Type of the attribute [:attr_writer, :attr_reader or :attr_accessor]
|
19
22
|
def type
|
20
23
|
@type ||= if @reader.nil?
|
21
24
|
:attr_writer
|
@@ -24,6 +27,7 @@ module Peeky
|
|
24
27
|
end
|
25
28
|
end
|
26
29
|
|
30
|
+
# Name of the attribute
|
27
31
|
def name
|
28
32
|
@name ||= @reader.nil? ? @writer.clean_name : @reader.clean_name
|
29
33
|
end
|
data/lib/peeky/class_info.rb
CHANGED
@@ -17,6 +17,43 @@ module Peeky
|
|
17
17
|
@instance = instance
|
18
18
|
end
|
19
19
|
|
20
|
+
# rubocop:disable Metrics/AbcSize
|
21
|
+
def to_s
|
22
|
+
result = []
|
23
|
+
result.push kv('class', class_full_name)
|
24
|
+
if defined?(@_ruby_instance_method_names)
|
25
|
+
result.push kv('# of instance methods', @_ruby_instance_method_names.join(', '))
|
26
|
+
else
|
27
|
+
result.push kv('# of instance methods', '')
|
28
|
+
end
|
29
|
+
if defined?(@_signatures)
|
30
|
+
result.push kv('# of accessors', accessors.length)
|
31
|
+
result.push kv('# of readers', readers.length)
|
32
|
+
result.push kv('# of writers', writers.length)
|
33
|
+
result.push kv('# of methods', methods.length)
|
34
|
+
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', '')
|
39
|
+
end
|
40
|
+
result.join("\n")
|
41
|
+
end
|
42
|
+
# rubocop:enable Metrics/AbcSize
|
43
|
+
|
44
|
+
# Load class_info
|
45
|
+
#
|
46
|
+
# Accessing information about methods and parameters is currently
|
47
|
+
# lazy-loaded via memoization.
|
48
|
+
#
|
49
|
+
# At times during debug or other edge cases, it may be useful to
|
50
|
+
# pre-load this information early.
|
51
|
+
def load
|
52
|
+
ruby_instance_methods
|
53
|
+
ruby_instance_method_names
|
54
|
+
signatures
|
55
|
+
end
|
56
|
+
|
20
57
|
# Class full name includes the module namespace
|
21
58
|
def class_full_name
|
22
59
|
instance.class.name
|
@@ -144,45 +181,12 @@ module Peeky
|
|
144
181
|
signatures.select { |im| im.name == name && im.implementation_type == filter_type }
|
145
182
|
end
|
146
183
|
|
147
|
-
|
148
|
-
# TODO: Refact: Currently the idea is to pre-load data
|
149
|
-
# this is slower when you are not accessing things, but
|
150
|
-
# it is easier to debug, so think about what I really want
|
151
|
-
# here
|
152
|
-
def build
|
153
|
-
ruby_instance_methods
|
154
|
-
ruby_instance_method_names
|
155
|
-
signatures
|
156
|
-
end
|
184
|
+
private
|
157
185
|
|
158
|
-
|
159
|
-
|
160
|
-
# Refact: PATTERN: Come up it an debug inclusion system so that
|
161
|
-
# so that debug helpers can be included for development and excluded
|
162
|
-
# for production
|
163
|
-
# @param format [String] format: <value for format> (optional)
|
164
|
-
def debug(format: [:signatures])
|
165
|
-
debug_method_names if format.include?(:method_names)
|
166
|
-
|
167
|
-
return unless format.include?(:signatures)
|
168
|
-
|
169
|
-
puts '-' * 70
|
170
|
-
puts 'Methods'
|
171
|
-
puts '-' * 70
|
172
|
-
signatures.each(&:debug)
|
173
|
-
end
|
174
|
-
|
175
|
-
def debug_method_names
|
176
|
-
puts '-' * 70
|
177
|
-
puts 'Method Names'
|
178
|
-
puts '-' * 70
|
179
|
-
ruby_instance_method_names.each do |method_name|
|
180
|
-
puts method_name
|
181
|
-
end
|
186
|
+
def kv(key, value)
|
187
|
+
"#{key.to_s.ljust(25)}: #{value}"
|
182
188
|
end
|
183
189
|
|
184
|
-
private
|
185
|
-
|
186
190
|
def ruby_instance_method_names
|
187
191
|
@_ruby_instance_method_names ||= instance.class.instance_methods(false).sort
|
188
192
|
end
|
@@ -47,16 +47,16 @@ module Peeky
|
|
47
47
|
# F method with required param and optional param
|
48
48
|
#
|
49
49
|
# @param first_name [String] first name (required)
|
50
|
-
# @param last_name [String]
|
51
|
-
def f_method_with_required_param_and_optional_param(first_name, last_name =
|
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
52
|
end
|
53
53
|
|
54
54
|
# G method with required param and two optional params
|
55
55
|
#
|
56
56
|
# @param first_name [String] first name (required)
|
57
|
-
# @param last_name [String]
|
58
|
-
# @param age [
|
59
|
-
def g_method_with_required_param_and_two_optional_params(first_name, last_name =
|
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
60
|
end
|
61
61
|
|
62
62
|
# H list of optional parameters
|
@@ -79,6 +79,12 @@ module Peeky
|
|
79
79
|
def j_method_with_list_of_named_arguments(**options)
|
80
80
|
end
|
81
81
|
|
82
|
+
# Jin
|
83
|
+
#
|
84
|
+
# @param aaa [String] aaa (required)
|
85
|
+
def jin(aaa)
|
86
|
+
end
|
87
|
+
|
82
88
|
# K method with block
|
83
89
|
#
|
84
90
|
# @param code_block [Block] &code_block
|
@@ -94,11 +100,12 @@ module Peeky
|
|
94
100
|
# N method with key value param required and optional key value
|
95
101
|
#
|
96
102
|
# @param last_name [String] last_name: <value for last name> (required)
|
97
|
-
# @param salutation [String] salutation:
|
98
|
-
def n_method_with_key_value_param_required_and_optional_key_value(last_name:, salutation:
|
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')
|
99
105
|
end
|
100
106
|
|
101
107
|
# P available?
|
108
|
+
|
102
109
|
# @return [Boolean] true when p available?
|
103
110
|
def p_available?
|
104
111
|
end
|
@@ -110,13 +117,29 @@ module Peeky
|
|
110
117
|
# Z complex
|
111
118
|
#
|
112
119
|
# @param aaa [String] aaa (required)
|
113
|
-
# @param bbb [
|
120
|
+
# @param bbb [Integer] bbb is optional, defaults to 1
|
114
121
|
# @param ccc [Array<Object>] *ccc - list of ccc
|
115
122
|
# @param ddd [String] ddd: <value for ddd> (required)
|
116
|
-
# @param eee [
|
123
|
+
# @param eee [Integer] eee: is optional, defaults to 1
|
117
124
|
# @param fff [<key: value>...] **fff - list of key/values
|
118
125
|
# @param ggg [Block] &ggg
|
119
|
-
def z_complex(aaa, bbb =
|
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: )
|
120
143
|
end
|
121
144
|
end
|
122
145
|
end
|
data/lib/peeky/method_info.rb
CHANGED
@@ -16,26 +16,35 @@ module Peeky
|
|
16
16
|
|
17
17
|
def_delegators :focal_method, :name, :receiver, :arity, :super_method
|
18
18
|
|
19
|
-
|
19
|
+
## Stage 2 is the method likely to be an attribute reader or writer
|
20
|
+
#
|
20
21
|
|
21
22
|
# Implementation type indicates the probable representation of this
|
22
23
|
# method in ruby, was it `def method` or `attr_reader` / `attr_writer`
|
23
24
|
attr_reader :implementation_type
|
24
25
|
|
25
|
-
|
26
|
-
def initialize(method, target_instance = nil)
|
26
|
+
def initialize(method, target_instance)
|
27
27
|
@focal_method = method
|
28
|
+
@target_instance = target_instance
|
28
29
|
@parameters = ParameterInfo.from_method(method)
|
29
30
|
# stage 1
|
30
31
|
# @implementation_type = :method
|
31
32
|
|
32
33
|
# stage 2
|
33
|
-
|
34
|
+
infer_implementation_type
|
35
|
+
|
36
|
+
# stage 3
|
37
|
+
infer_default_paramaters
|
34
38
|
end
|
35
39
|
|
36
40
|
# Stage 2 (working out) attr_accessor
|
41
|
+
#
|
42
|
+
|
37
43
|
# Name of method minus writer annotations
|
38
|
-
# Example
|
44
|
+
# Example
|
45
|
+
# :writable_attribute=
|
46
|
+
# # becomes
|
47
|
+
# :writable_attribute
|
39
48
|
def clean_name
|
40
49
|
@clean_name ||= begin
|
41
50
|
n = name.to_s
|
@@ -43,43 +52,113 @@ module Peeky
|
|
43
52
|
end
|
44
53
|
end
|
45
54
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
+
# Infer implementation type [:method, :attr_reader or :attr_writer]
|
56
|
+
# rubocop:disable Lint/DuplicateBranch
|
57
|
+
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
|
67
|
+
end
|
68
|
+
# rubocop:enable Lint/DuplicateBranch
|
69
|
+
|
70
|
+
# Get parameter by name
|
71
|
+
#
|
72
|
+
# @param name [String] name (required)
|
73
|
+
def get_parameter(name)
|
74
|
+
name = name.to_s
|
75
|
+
parameters.find { |p| p.name == name }
|
76
|
+
end
|
77
|
+
|
78
|
+
# Has any optional paramaters?
|
79
|
+
|
80
|
+
# @return [Boolean] true when any parameter is optional?
|
81
|
+
def optional?
|
82
|
+
parameters.any?(&:optional?)
|
83
|
+
end
|
84
|
+
|
85
|
+
# Infer default paramater values
|
86
|
+
#
|
87
|
+
# WARNING: Unit test coverage went from .1 seconds to 30-40 seconds
|
88
|
+
# when I first introduced this method.
|
89
|
+
#
|
90
|
+
# I now only call TracePoint if I have optional parameters to be inferred.
|
91
|
+
#
|
92
|
+
# The tests are now down to 5 seconds, but it highlights the cost of use
|
93
|
+
# TracePoint.
|
94
|
+
def infer_default_paramaters
|
95
|
+
minimalist_method = Peeky::Renderer::MethodCallMinimumParamsRender.new(self).render
|
96
|
+
|
97
|
+
return if minimalist_method.end_with?('=')
|
98
|
+
return unless optional?
|
99
|
+
|
100
|
+
tracer.enable do
|
101
|
+
@target_instance.instance_eval(minimalist_method)
|
102
|
+
rescue StandardError => e
|
103
|
+
# just print the error for now, we are only attempting to capture the
|
104
|
+
# first call, any errors inside the call cannot be dealt with and should
|
105
|
+
# not be re-raised
|
106
|
+
puts e.message
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def tracer
|
111
|
+
TracePoint.trace(:call, :c_call) do |tp|
|
112
|
+
next unless tp.self.is_a?(@target_instance.class)
|
113
|
+
next unless tp.method_id == name
|
114
|
+
|
115
|
+
tp.parameters.each do |_type, param_name|
|
116
|
+
method_paramater = get_parameter(param_name)
|
117
|
+
|
118
|
+
if method_paramater.optional?
|
119
|
+
value = tp.binding.local_variable_get(param_name)
|
120
|
+
method_paramater.default_value = value
|
121
|
+
end
|
122
|
+
end
|
55
123
|
end
|
56
124
|
end
|
57
125
|
|
58
|
-
|
59
|
-
|
126
|
+
# Match
|
127
|
+
#
|
128
|
+
# @param predicate [String] use a predicate object with the signature match(instance, method_info)
|
129
|
+
def match(predicate)
|
130
|
+
predicate.new.match(@target_instance, self)
|
60
131
|
end
|
61
132
|
|
133
|
+
# Method?
|
134
|
+
|
135
|
+
# @return [Boolean] true when implementation type is method?
|
62
136
|
def method?
|
63
137
|
@implementation_type == :method
|
64
138
|
end
|
65
139
|
|
66
|
-
#
|
67
|
-
#
|
68
|
-
#
|
69
|
-
# Cannot read property 'namedChildren' of undefined
|
140
|
+
# Readable?
|
141
|
+
#
|
142
|
+
# @return [Boolean] true when readable?
|
70
143
|
def readable?
|
144
|
+
# Method naming issue: VSCode Ruby Language Server
|
145
|
+
#
|
146
|
+
# If this method is renamed to attr_readable, same for attr_writable.
|
147
|
+
#
|
148
|
+
# https://github.com/rubyide/vscode-ruby/issues/454
|
149
|
+
# if I prefix these methods with attr_ then will get an issue
|
150
|
+
# in the language server.
|
151
|
+
#
|
152
|
+
# Cannot read property 'namedChildren' of undefined
|
153
|
+
|
71
154
|
@implementation_type == :attr_reader
|
72
155
|
end
|
73
156
|
|
157
|
+
# Writable?
|
158
|
+
|
159
|
+
# @return [Boolean] true when implementation_type writable?
|
74
160
|
def writable?
|
75
161
|
@implementation_type == :attr_writer
|
76
162
|
end
|
77
|
-
|
78
|
-
def debug
|
79
|
-
puts '-' * 70
|
80
|
-
puts name
|
81
|
-
puts '-' * 70
|
82
|
-
parameters.each(&:debug)
|
83
|
-
end
|
84
163
|
end
|
85
164
|
end
|
data/lib/peeky/parameter_info.rb
CHANGED
@@ -20,11 +20,8 @@ module Peeky
|
|
20
20
|
# type of the parameter
|
21
21
|
attr_accessor :type
|
22
22
|
|
23
|
-
#
|
24
|
-
attr_accessor :
|
25
|
-
|
26
|
-
# minimal required usage in a call to the method with this paramater
|
27
|
-
attr_accessor :minimal_call_format
|
23
|
+
# default value for positional or keyed parameters
|
24
|
+
attr_accessor :default_value
|
28
25
|
|
29
26
|
def initialize(param)
|
30
27
|
map(param)
|
@@ -51,54 +48,133 @@ module Peeky
|
|
51
48
|
ruby_method.parameters.map { |ruby_paramater| from_parameter(ruby_paramater) }
|
52
49
|
end
|
53
50
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
51
|
+
# ruby code formatted for use in a method signature
|
52
|
+
def signature_format
|
53
|
+
@_signature_format ||= begin
|
54
|
+
method_name = "signature_format_#{@type}".to_sym
|
55
|
+
|
56
|
+
m = method(method_name)
|
57
|
+
m.call
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# minimal required usage in a call to the method with this paramater
|
62
|
+
def minimal_call_format
|
63
|
+
@_minimal_call_format ||= begin
|
64
|
+
method_name = "minimal_call_format_#{@type}".to_sym
|
65
|
+
|
66
|
+
if respond_to?(method_name, true)
|
67
|
+
m = method(method_name)
|
68
|
+
m.call
|
69
|
+
else
|
70
|
+
minimal_call_format_ignore
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Optional?
|
76
|
+
|
77
|
+
# @return [Boolean] true when parameter is one of the optional types?
|
78
|
+
def optional?
|
79
|
+
@_optional |= (@type == :param_optional || @type == :key_optional)
|
80
|
+
end
|
81
|
+
|
82
|
+
# Default value type will look at the default value and try to
|
83
|
+
# infer the class behind it. Will default to 'Object' fi nil
|
84
|
+
def default_value_type
|
85
|
+
if @default_value.nil?
|
86
|
+
'Object'
|
87
|
+
else
|
88
|
+
@default_value.class
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# Wrap default value in quotes if string, or no wrapping otherwise
|
93
|
+
#
|
94
|
+
# @param value_for_nil [String] value for nil, generally '' or 'nil' (required)
|
95
|
+
def wrap_default_value(value_for_nil)
|
96
|
+
if @default_value.is_a?(String)
|
97
|
+
"'#{@default_value}'"
|
98
|
+
else
|
99
|
+
@default_value.nil? ? value_for_nil : @default_value
|
100
|
+
end
|
59
101
|
end
|
60
102
|
|
61
103
|
private
|
62
104
|
|
63
105
|
# Convert the limited information provided by ruby method.parameters
|
64
106
|
# to a richer structure.
|
65
|
-
# rubocop:disable Metrics/
|
107
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
66
108
|
def map(param)
|
67
109
|
@name = param.length > 1 ? param[1].to_s : ''
|
68
110
|
|
111
|
+
@default_value = nil
|
112
|
+
|
69
113
|
case param[0]
|
70
114
|
when :req
|
71
115
|
@type = :param_required
|
72
|
-
@signature_format = name.to_s
|
73
|
-
@minimal_call_format = "'#{name}'"
|
74
116
|
when :opt
|
75
117
|
@type = :param_optional
|
76
|
-
@signature_format = "#{name} = nil"
|
77
|
-
@minimal_call_format = ''
|
78
118
|
when :rest
|
79
119
|
@type = :splat
|
80
|
-
@signature_format = "*#{name}"
|
81
|
-
@minimal_call_format = ''
|
82
120
|
when :keyreq
|
83
121
|
@type = :key_required
|
84
|
-
@signature_format = "#{name}:"
|
85
|
-
@minimal_call_format = "#{name}: '#{name}'"
|
86
122
|
when :key
|
87
123
|
@type = :key_optional
|
88
|
-
@signature_format = "#{name}: nil"
|
89
|
-
@minimal_call_format = ''
|
90
124
|
when :keyrest
|
91
125
|
@type = :double_splat
|
92
|
-
@signature_format = "**#{name}"
|
93
|
-
@minimal_call_format = ''
|
94
126
|
when :block
|
95
127
|
@type = :block
|
96
|
-
@signature_format = "&#{name}"
|
97
|
-
@minimal_call_format = ''
|
98
128
|
else
|
99
129
|
raise 'unknown type'
|
100
130
|
end
|
101
131
|
end
|
102
|
-
# rubocop:enable Metrics/
|
132
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
133
|
+
|
134
|
+
# Signature format *: Is used to format a parameter when it is used
|
135
|
+
# inside of a method signature, eg. def my_method(p1, p2 = 'xyz', p3: :name_value)
|
136
|
+
|
137
|
+
def signature_format_param_required
|
138
|
+
name.to_s
|
139
|
+
end
|
140
|
+
|
141
|
+
def signature_format_param_optional
|
142
|
+
"#{name} = #{wrap_default_value('nil')}" # signature format needs to be moved to a method
|
143
|
+
end
|
144
|
+
|
145
|
+
def signature_format_splat
|
146
|
+
"*#{name}"
|
147
|
+
end
|
148
|
+
|
149
|
+
def signature_format_key_required
|
150
|
+
"#{name}:"
|
151
|
+
end
|
152
|
+
|
153
|
+
def signature_format_key_optional
|
154
|
+
"#{name}: #{wrap_default_value('')}"
|
155
|
+
end
|
156
|
+
|
157
|
+
def signature_format_double_splat
|
158
|
+
"**#{name}"
|
159
|
+
end
|
160
|
+
|
161
|
+
def signature_format_block
|
162
|
+
"&#{name}"
|
163
|
+
end
|
164
|
+
|
165
|
+
# Minimal call format *: Is used to format a call to a method with the least
|
166
|
+
# number of parameters needed to make it work.
|
167
|
+
|
168
|
+
def minimal_call_format_ignore
|
169
|
+
''
|
170
|
+
end
|
171
|
+
|
172
|
+
def minimal_call_format_param_required
|
173
|
+
"'#{@name}'"
|
174
|
+
end
|
175
|
+
|
176
|
+
def minimal_call_format_key_required
|
177
|
+
"#{@name}: '#{@name}'"
|
178
|
+
end
|
103
179
|
end
|
104
180
|
end
|