inch 0.2.2 → 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +170 -56
- data/TODOS.md +0 -6
- data/config/defaults.rb +82 -0
- data/lib/inch/cli/command/base.rb +9 -0
- data/lib/inch/cli/command/base_list.rb +8 -8
- data/lib/inch/cli/command/base_object.rb +1 -1
- data/lib/inch/cli/command/list.rb +6 -1
- data/lib/inch/cli/command/options/base.rb +1 -1
- data/lib/inch/cli/command/options/suggest.rb +3 -1
- data/lib/inch/cli/command/output/list.rb +6 -6
- data/lib/inch/cli/command/output/show.rb +3 -3
- data/lib/inch/cli/command/output/stats.rb +52 -33
- data/lib/inch/cli/command/output/suggest.rb +7 -7
- data/lib/inch/cli/command/show.rb +5 -0
- data/lib/inch/cli/command/stats.rb +6 -1
- data/lib/inch/cli/command/suggest.rb +31 -12
- data/lib/inch/cli/command.rb +7 -14
- data/lib/inch/cli/command_parser.rb +2 -9
- data/lib/inch/cli/sparkline_helper.rb +13 -13
- data/lib/inch/cli/weighted_list.rb +85 -0
- data/lib/inch/cli.rb +2 -1
- data/lib/inch/code_object/nodoc_helper.rb +2 -0
- data/lib/inch/code_object/proxy/base.rb +36 -13
- data/lib/inch/code_object/proxy/method_object.rb +29 -0
- data/lib/inch/code_object/proxy/namespace_object.rb +6 -0
- data/lib/inch/config.rb +30 -37
- data/lib/inch/evaluation/base.rb +53 -1
- data/lib/inch/evaluation/constant_object.rb +8 -11
- data/lib/inch/evaluation/file.rb +1 -1
- data/lib/inch/evaluation/grade.rb +41 -0
- data/lib/inch/evaluation/grade_list.rb +32 -0
- data/lib/inch/evaluation/method_object.rb +10 -51
- data/lib/inch/evaluation/namespace_object.rb +8 -49
- data/lib/inch/evaluation/{criteria.rb → object_schema.rb} +12 -22
- data/lib/inch/evaluation/read_write_methods.rb +21 -0
- data/lib/inch/evaluation/role/method.rb +8 -0
- data/lib/inch/evaluation.rb +5 -2
- data/lib/inch/version.rb +1 -1
- data/lib/inch.rb +3 -1
- data/test/fixtures/simple/lib/broken.rb +15 -0
- data/test/fixtures/simple/lib/role_methods.rb +15 -0
- data/test/inch/cli/weighted_list_test.rb +55 -0
- data/test/inch/code_object/proxy/method_object_test.rb +42 -0
- data/test/integration/stats_options_test.rb +1 -1
- metadata +11 -5
- data/lib/inch/evaluation/score_range.rb +0 -38
@@ -16,10 +16,10 @@ module Inch
|
|
16
16
|
[203, 203, 204, 204, 205, 206, 207]
|
17
17
|
].flatten.map { |s| :"color#{s}" }
|
18
18
|
|
19
|
-
def initialize(options, objects,
|
19
|
+
def initialize(options, objects, grade_lists)
|
20
20
|
@options = options
|
21
21
|
@objects = objects
|
22
|
-
@
|
22
|
+
@grade_lists = grade_lists
|
23
23
|
|
24
24
|
method("display_#{@options.format}").call
|
25
25
|
end
|
@@ -27,19 +27,23 @@ module Inch
|
|
27
27
|
private
|
28
28
|
|
29
29
|
def display_text
|
30
|
-
|
31
|
-
|
30
|
+
print_grades
|
31
|
+
print_grades_by_priority
|
32
|
+
print_priorities
|
32
33
|
puts
|
33
34
|
puts 'Try `--format json|yaml` for raw numbers.'.dark
|
34
35
|
end
|
35
36
|
|
36
|
-
def
|
37
|
-
sparkline =
|
37
|
+
def print_grades
|
38
|
+
sparkline = grade_lists_sparkline(@grade_lists).to_s(' ')
|
38
39
|
puts
|
39
40
|
puts 'Grade distribution: (undocumented, C, B, A)'
|
40
41
|
puts
|
41
42
|
puts " Overall: #{sparkline} #{objects.size.to_s.rjust(5)} objects"
|
42
43
|
puts
|
44
|
+
end
|
45
|
+
|
46
|
+
def print_grades_by_priority
|
43
47
|
puts 'Grade distribution by priority:'
|
44
48
|
puts
|
45
49
|
PRIORITY_MAP.each do |priority_range, arrow|
|
@@ -51,25 +55,29 @@ module Inch
|
|
51
55
|
end
|
52
56
|
end
|
53
57
|
|
54
|
-
def
|
58
|
+
def print_grade_list(grade_list)
|
59
|
+
list = grade_list.objects.map(&:priority)
|
60
|
+
|
61
|
+
priorities = {}
|
62
|
+
(-7..7).each do |key|
|
63
|
+
priorities[key.to_s] = list.select { |p| p == key }.size
|
64
|
+
end
|
65
|
+
|
66
|
+
sparkline = Sparkr::Sparkline.new(priorities.values)
|
67
|
+
sparkline.format do |tick, count, index|
|
68
|
+
tick.color( PRIORITY_COLORS[index] )
|
69
|
+
end
|
70
|
+
puts " #{grade_list.grade}: " + sparkline.to_s(' ') +
|
71
|
+
" #{grade_list.objects.size.to_s.rjust(5)} objects"
|
72
|
+
puts
|
73
|
+
end
|
74
|
+
|
75
|
+
def print_priorities
|
55
76
|
puts "Priority distribution in grades: (low to high)"
|
56
77
|
puts
|
57
78
|
puts " #{PRIORITY_MAP.values.reverse.join(' ')}"
|
58
|
-
@
|
59
|
-
|
60
|
-
|
61
|
-
priorities = {}
|
62
|
-
(-7..7).each do |key|
|
63
|
-
priorities[key.to_s] = list.select { |p| p == key }.size
|
64
|
-
end
|
65
|
-
|
66
|
-
sparkline = Sparkr::Sparkline.new(priorities.values)
|
67
|
-
sparkline.format do |tick, count, index|
|
68
|
-
tick.color( PRIORITY_COLORS[index] )
|
69
|
-
end
|
70
|
-
puts " #{range.grade}: " + sparkline.to_s(' ') +
|
71
|
-
" #{range.objects.size.to_s.rjust(5)} objects"
|
72
|
-
puts
|
79
|
+
@grade_lists.reverse.each do |grade_list|
|
80
|
+
print_grade_list(grade_list)
|
73
81
|
end
|
74
82
|
end
|
75
83
|
|
@@ -82,25 +90,36 @@ module Inch
|
|
82
90
|
end
|
83
91
|
|
84
92
|
def stats_hash
|
85
|
-
|
93
|
+
{
|
94
|
+
'grade_lists' => __grade_lists,
|
95
|
+
'scores' => __scores,
|
96
|
+
'priorities' => __priorities
|
97
|
+
}
|
98
|
+
end
|
86
99
|
|
87
|
-
|
88
|
-
|
89
|
-
|
100
|
+
def __grade_lists
|
101
|
+
hash = {}
|
102
|
+
@grade_lists.each do |r|
|
103
|
+
hash[r.grade.to_s] = r.objects.size
|
90
104
|
end
|
105
|
+
hash
|
106
|
+
end
|
91
107
|
|
92
|
-
|
108
|
+
def __scores
|
109
|
+
hash = {}
|
93
110
|
@objects.sort_by(&:score).each do |o|
|
94
|
-
hash[
|
95
|
-
hash[
|
111
|
+
hash[o.score.to_i] ||= 0
|
112
|
+
hash[o.score.to_i] += 1
|
96
113
|
end
|
114
|
+
hash
|
115
|
+
end
|
97
116
|
|
98
|
-
|
117
|
+
def __priorities
|
118
|
+
hash = {}
|
99
119
|
@objects.sort_by(&:priority).each do |o|
|
100
|
-
hash[
|
101
|
-
hash[
|
120
|
+
hash[o.priority.to_i] ||= 0
|
121
|
+
hash[o.priority.to_i] += 1
|
102
122
|
end
|
103
|
-
|
104
123
|
hash
|
105
124
|
end
|
106
125
|
|
@@ -20,13 +20,13 @@ module Inch
|
|
20
20
|
# @param options [Command::Options::Suggest]
|
21
21
|
# @param objects_to_display [Array<CodeObject::Proxy::Base>]
|
22
22
|
# @param relevant_objects [Array<CodeObject::Proxy::Base>] the objects meeting the criteria defined in +options+
|
23
|
-
# @param
|
23
|
+
# @param grade_lists [Array<Evaluation::GradeList>]
|
24
24
|
# @param files [Array<Evaluation::File>]
|
25
|
-
def initialize(options, objects_to_display, relevant_objects,
|
25
|
+
def initialize(options, objects_to_display, relevant_objects, grade_lists, files)
|
26
26
|
@options = options
|
27
27
|
@objects = objects_to_display
|
28
28
|
@relevant_objects = relevant_objects
|
29
|
-
@
|
29
|
+
@grade_lists = grade_lists
|
30
30
|
@files = files
|
31
31
|
|
32
32
|
if objects.empty?
|
@@ -70,11 +70,11 @@ module Inch
|
|
70
70
|
|
71
71
|
def display_list
|
72
72
|
@options.grades_to_display.map do |grade|
|
73
|
-
r =
|
73
|
+
r = grade_list(grade)
|
74
74
|
grade_objects = objects.select { |o| o.grade == r.grade }
|
75
75
|
unless grade_objects.empty?
|
76
76
|
trace
|
77
|
-
trace_header(RANGE_LABELS[r.grade], r.color, r.bg_color)
|
77
|
+
trace_header(RANGE_LABELS[r.grade.to_sym], r.color, r.bg_color)
|
78
78
|
grade_objects.each do |o|
|
79
79
|
grade = o.grade.to_s.ljust(2).color(r.color)
|
80
80
|
priority = o.priority
|
@@ -94,8 +94,8 @@ module Inch
|
|
94
94
|
end.compact
|
95
95
|
end
|
96
96
|
|
97
|
-
def
|
98
|
-
@
|
97
|
+
def grade_list(grade_symbol)
|
98
|
+
@grade_lists.detect { |r| r.grade.to_sym == grade_symbol }
|
99
99
|
end
|
100
100
|
end
|
101
101
|
end
|
@@ -1,7 +1,12 @@
|
|
1
|
+
require_relative 'options/stats'
|
2
|
+
require_relative 'output/stats'
|
3
|
+
|
1
4
|
module Inch
|
2
5
|
module CLI
|
3
6
|
module Command
|
4
7
|
class Stats < List
|
8
|
+
register_command_as :stats
|
9
|
+
|
5
10
|
def description
|
6
11
|
'Lists all objects with their results'
|
7
12
|
end
|
@@ -12,7 +17,7 @@ module Inch
|
|
12
17
|
|
13
18
|
def run(*args)
|
14
19
|
prepare_list(*args)
|
15
|
-
Output::Stats.new(@options, objects, @
|
20
|
+
Output::Stats.new(@options, objects, @grade_lists)
|
16
21
|
end
|
17
22
|
end
|
18
23
|
end
|
@@ -1,7 +1,12 @@
|
|
1
|
+
require_relative 'options/suggest'
|
2
|
+
require_relative 'output/suggest'
|
3
|
+
|
1
4
|
module Inch
|
2
5
|
module CLI
|
3
6
|
module Command
|
4
7
|
class Suggest < List
|
8
|
+
register_command_as :suggest, true
|
9
|
+
|
5
10
|
def description
|
6
11
|
'Suggests some objects to be doucmented (better)'
|
7
12
|
end
|
@@ -17,29 +22,43 @@ module Inch
|
|
17
22
|
# @return [void]
|
18
23
|
def run(*args)
|
19
24
|
prepare_list(*args)
|
20
|
-
Output::Suggest.new(@options, objects_to_display, relevant_objects, @
|
25
|
+
Output::Suggest.new(@options, objects_to_display, relevant_objects, @grade_lists, files)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
# @return [Fixnum] how many objects should be displayed in the output
|
31
|
+
def object_count
|
32
|
+
@options.object_count
|
33
|
+
end
|
34
|
+
|
35
|
+
# @return [Array<Fixnum>]
|
36
|
+
# how many objects of each grade should be displayed in the output
|
37
|
+
def object_list_counts
|
38
|
+
@options.grade_weights.map { |w| w * object_count }
|
21
39
|
end
|
22
40
|
|
41
|
+
# @return [Array] the objects that should be displayed in the output
|
23
42
|
def objects_to_display
|
24
43
|
@objects_to_display ||= filter_objects_to_display
|
25
44
|
end
|
26
45
|
|
46
|
+
# @return [Array] the objects that should be displayed in the output
|
27
47
|
def filter_objects_to_display
|
28
|
-
|
48
|
+
grade_list = []
|
29
49
|
@options.grades_to_display.map do |grade|
|
30
|
-
r =
|
50
|
+
r = grade_list(grade)
|
31
51
|
arr = select_by_priority(r.objects, @options.object_min_priority)
|
32
52
|
arr = arr.select { |o| o.score <= @options.object_max_score }
|
33
|
-
|
53
|
+
grade_list << arr
|
34
54
|
end
|
35
55
|
|
36
|
-
|
56
|
+
weighted_list = WeightedList.new(grade_list, object_list_counts)
|
57
|
+
|
58
|
+
list = sort_by_priority(weighted_list.to_a.flatten)
|
37
59
|
|
38
|
-
if list.size >
|
39
|
-
list = list[0
|
40
|
-
elsif list.size < @options.object_count
|
41
|
-
# should we add objects with lower priority to fill out the
|
42
|
-
# requested count?
|
60
|
+
if list.size > object_count
|
61
|
+
list = list[0...object_count]
|
43
62
|
end
|
44
63
|
list
|
45
64
|
end
|
@@ -78,8 +97,8 @@ module Inch
|
|
78
97
|
objects.map(&:grade).uniq
|
79
98
|
end
|
80
99
|
|
81
|
-
def
|
82
|
-
@
|
100
|
+
def grade_list(grade_symbol)
|
101
|
+
@grade_lists.detect { |r| r.grade.to_sym == grade_symbol }
|
83
102
|
end
|
84
103
|
|
85
104
|
def relevant_objects
|
data/lib/inch/cli/command.rb
CHANGED
@@ -2,22 +2,15 @@ require_relative 'command/base'
|
|
2
2
|
require_relative 'command/base_list'
|
3
3
|
require_relative 'command/base_object'
|
4
4
|
|
5
|
-
require_relative 'command/list'
|
6
|
-
require_relative 'command/show'
|
7
|
-
require_relative 'command/stats'
|
8
|
-
require_relative 'command/suggest'
|
9
|
-
|
10
5
|
require_relative 'command/options/base'
|
11
6
|
require_relative 'command/options/base_list'
|
12
7
|
require_relative 'command/options/base_object'
|
13
8
|
|
14
|
-
require_relative 'command/options/list'
|
15
|
-
require_relative 'command/options/show'
|
16
|
-
require_relative 'command/options/stats'
|
17
|
-
require_relative 'command/options/suggest'
|
18
|
-
|
19
9
|
require_relative 'command/output/base'
|
20
|
-
|
21
|
-
require_relative '
|
22
|
-
|
23
|
-
require_relative 'command/
|
10
|
+
|
11
|
+
require_relative 'command_parser'
|
12
|
+
|
13
|
+
require_relative 'command/list'
|
14
|
+
require_relative 'command/show'
|
15
|
+
require_relative 'command/stats'
|
16
|
+
require_relative 'command/suggest'
|
@@ -43,15 +43,8 @@ module Inch
|
|
43
43
|
attr_accessor :default_command
|
44
44
|
end
|
45
45
|
|
46
|
-
self.commands = {
|
47
|
-
|
48
|
-
:show => Command::Show,
|
49
|
-
:stats => Command::Stats,
|
50
|
-
:suggest => Command::Suggest,
|
51
|
-
}
|
52
|
-
|
53
|
-
self.default_command = :suggest
|
54
|
-
|
46
|
+
self.commands = {}
|
47
|
+
|
55
48
|
# Convenience method to create a new CommandParser and call {#run}
|
56
49
|
# @return (see #run)
|
57
50
|
def self.run(*args)
|
@@ -1,28 +1,28 @@
|
|
1
1
|
module Inch
|
2
2
|
module CLI
|
3
3
|
module SparklineHelper
|
4
|
-
def
|
5
|
-
|
6
|
-
list =
|
7
|
-
|
8
|
-
sparkline.format do |tick, count, index|
|
9
|
-
t = tick.color(ranges[index].color)
|
10
|
-
index == 0 ? t + ' ' : t
|
11
|
-
end
|
4
|
+
def grade_lists_sparkline(_grade_lists)
|
5
|
+
grade_lists = _grade_lists.reverse
|
6
|
+
list = grade_lists.map { |r| r.objects.size }
|
7
|
+
__sparkline(list, grade_lists)
|
12
8
|
end
|
13
9
|
|
14
10
|
def grades_sparkline(objects)
|
15
11
|
grades = {}
|
16
12
|
objects.each do |o|
|
17
|
-
grades[o.grade] ||= 0
|
18
|
-
grades[o.grade] += 1
|
13
|
+
grades[o.grade.to_sym] ||= 0
|
14
|
+
grades[o.grade.to_sym] += 1
|
19
15
|
end
|
20
|
-
|
21
|
-
order =
|
16
|
+
grade_lists = Evaluation.new_grade_lists.reverse
|
17
|
+
order = grade_lists.map(&:to_sym)
|
22
18
|
list = order.map { |g| grades[g] }
|
19
|
+
__sparkline(list, grade_lists)
|
20
|
+
end
|
21
|
+
|
22
|
+
def __sparkline(list, grade_lists)
|
23
23
|
sparkline = Sparkr::Sparkline.new(list)
|
24
24
|
sparkline.format do |tick, count, index|
|
25
|
-
t = tick.color(
|
25
|
+
t = tick.color(grade_lists[index].color)
|
26
26
|
index == 0 ? t + ' ' : t
|
27
27
|
end
|
28
28
|
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module Inch
|
2
|
+
module CLI
|
3
|
+
class WeightedList
|
4
|
+
# Trims down a list of object lists to given sizes.
|
5
|
+
# If there are not enough objects in any particular tier,
|
6
|
+
# they are filled up from the tier below/above.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
#
|
10
|
+
# list = [
|
11
|
+
# [:B1, :B2],
|
12
|
+
# [:C1, :C2, :C3, :C4, :C5, :C6, :C7, :C8, :C9, :C10],
|
13
|
+
# [:U1, :U2, :U3, :U4, :U5, :U6, :U7, :U8, :U9, :U10]
|
14
|
+
# ]
|
15
|
+
# counts = [4, 8, 8]
|
16
|
+
#
|
17
|
+
# This means there should be 4 +:B+s, 8 +:C+s, and 8 +:U+s in the
|
18
|
+
# resulting list. But we only have 2 +:B+s, so the result is filled up
|
19
|
+
# with +:U+s:
|
20
|
+
#
|
21
|
+
# WeightedList.new(list, counts).to_a
|
22
|
+
# # => [
|
23
|
+
# [:B1, :B2],
|
24
|
+
# [:C1, :C2, :C3, :C4, :C5, :C6, :C7, :C8],
|
25
|
+
# [:U1, :U2, :U3, :U4, :U5, :U6, :U7, :U8, :U9, :U10]
|
26
|
+
# ]
|
27
|
+
#
|
28
|
+
# @param list_of_lists [Array<Array>]
|
29
|
+
# @param counts [Array<Fixnum>]
|
30
|
+
def initialize(list_of_lists, counts)
|
31
|
+
@original = list_of_lists
|
32
|
+
@max_counts = counts
|
33
|
+
compute_list
|
34
|
+
end
|
35
|
+
|
36
|
+
# @return [Array]
|
37
|
+
def to_a
|
38
|
+
@list
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def compute_list
|
44
|
+
@list = init_empty_list(@original.size)
|
45
|
+
still_missing = fill_list_with_predefined_sizes
|
46
|
+
|
47
|
+
# all sublists are now filled up to their max capacity but we might
|
48
|
+
# have missed some objects (+still_missing+), because there weren't
|
49
|
+
# enough
|
50
|
+
|
51
|
+
@original.reverse_each.with_index do |sublist, rear_index|
|
52
|
+
if still_missing > 0
|
53
|
+
index = @original.size - rear_index - 1
|
54
|
+
present_count = @max_counts[index]
|
55
|
+
not_yet_in_list = sublist[present_count..-1]
|
56
|
+
if not_yet_in_list
|
57
|
+
put_in_list = not_yet_in_list[0...still_missing]
|
58
|
+
@list[index].concat put_in_list
|
59
|
+
still_missing -= put_in_list.size
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def init_empty_list(sublist_count)
|
66
|
+
list = []
|
67
|
+
sublist_count.times { list << [] }
|
68
|
+
list
|
69
|
+
end
|
70
|
+
|
71
|
+
def fill_list_with_predefined_sizes
|
72
|
+
missing = 0
|
73
|
+
@original.each_with_index do |sublist, index|
|
74
|
+
target_count = @max_counts[index]
|
75
|
+
@list[index].concat sublist[0...target_count]
|
76
|
+
|
77
|
+
if sublist.size < target_count
|
78
|
+
missing += target_count - sublist.size
|
79
|
+
end
|
80
|
+
end
|
81
|
+
missing
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
data/lib/inch/cli.rb
CHANGED
@@ -17,11 +17,12 @@ module Inch
|
|
17
17
|
end
|
18
18
|
|
19
19
|
require_relative 'cli/arguments'
|
20
|
+
require_relative 'cli/weighted_list'
|
20
21
|
require_relative 'cli/sparkline_helper'
|
21
22
|
require_relative 'cli/trace_helper'
|
22
23
|
require_relative 'cli/yardopts_helper'
|
24
|
+
|
23
25
|
require_relative 'cli/command'
|
24
|
-
require_relative 'cli/command_parser'
|
25
26
|
|
26
27
|
console_rb = File.join(File.dirname(__FILE__), 'cli', 'command', 'console.rb')
|
27
28
|
if File.exists?(console_rb)
|
@@ -9,10 +9,10 @@ module Inch
|
|
9
9
|
include NodocHelper
|
10
10
|
|
11
11
|
# @return [YARD::CodeObjects::Base] the actual (YARD) code object
|
12
|
-
|
12
|
+
attr_reader :object
|
13
13
|
|
14
14
|
# @return [Symbol]
|
15
|
-
# when objects are assigned to
|
15
|
+
# when objects are assigned to GradeLists, this grade is set to
|
16
16
|
# enable easier querying for objects of a certain grade
|
17
17
|
attr_writer :grade
|
18
18
|
|
@@ -27,7 +27,7 @@ module Inch
|
|
27
27
|
|
28
28
|
# @param object [YARD::CodeObjects::Base] the actual (YARD) code object
|
29
29
|
def initialize(object)
|
30
|
-
|
30
|
+
@object = object
|
31
31
|
end
|
32
32
|
|
33
33
|
def api_tag?
|
@@ -35,7 +35,14 @@ module Inch
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def api_tag
|
38
|
-
|
38
|
+
tag(:api) || (parent && parent.api_tag)
|
39
|
+
end
|
40
|
+
|
41
|
+
# To be overridden
|
42
|
+
# @see Proxy::NamespaceObject
|
43
|
+
# @return [CodeObject::Proxy::Base,nil] the child inside the current object or +nil+
|
44
|
+
def child(name)
|
45
|
+
nil
|
39
46
|
end
|
40
47
|
|
41
48
|
# To be overridden
|
@@ -65,8 +72,8 @@ module Inch
|
|
65
72
|
|
66
73
|
# @return [Symbol]
|
67
74
|
def grade
|
68
|
-
@grade ||= Evaluation.
|
69
|
-
range.
|
75
|
+
@grade ||= Evaluation.new_grade_lists.detect { |range|
|
76
|
+
range.scores.include?(score)
|
70
77
|
}.grade
|
71
78
|
end
|
72
79
|
|
@@ -75,7 +82,7 @@ module Inch
|
|
75
82
|
end
|
76
83
|
|
77
84
|
def has_code_example?
|
78
|
-
!
|
85
|
+
!tags(:example).empty? ||
|
79
86
|
docstring.contains_code_example?
|
80
87
|
end
|
81
88
|
|
@@ -84,10 +91,10 @@ module Inch
|
|
84
91
|
end
|
85
92
|
|
86
93
|
def has_multiple_code_examples?
|
87
|
-
if
|
94
|
+
if tags(:example).size > 1 || docstring.code_examples.size > 1
|
88
95
|
true
|
89
96
|
else
|
90
|
-
if tag =
|
97
|
+
if tag = tag(:example)
|
91
98
|
multi_code_examples?(tag.text)
|
92
99
|
elsif text = docstring.code_examples.first
|
93
100
|
multi_code_examples?(text)
|
@@ -148,7 +155,11 @@ module Inch
|
|
148
155
|
# @return [Boolean]
|
149
156
|
# +true+ if the object or its parent is tagged as @private
|
150
157
|
def private_tag?
|
151
|
-
!
|
158
|
+
!private_tag.nil?
|
159
|
+
end
|
160
|
+
|
161
|
+
def private_tag
|
162
|
+
tag(:private) || (parent && parent.private_tag)
|
152
163
|
end
|
153
164
|
|
154
165
|
def private_api_tag?
|
@@ -165,13 +176,13 @@ module Inch
|
|
165
176
|
|
166
177
|
# @return [Boolean] +true+ if the object has no documentation at all
|
167
178
|
def undocumented?
|
168
|
-
docstring.empty? &&
|
179
|
+
docstring.empty? && tags.empty?
|
169
180
|
end
|
170
181
|
|
171
182
|
# @return [Array]
|
172
183
|
# YARD tags that are not already covered by other wrapper methods
|
173
184
|
def unconsidered_tags
|
174
|
-
@unconsidered_tags ||=
|
185
|
+
@unconsidered_tags ||= tags.reject do |tag|
|
175
186
|
CONSIDERED_YARD_TAGS.include?(tag.tag_name)
|
176
187
|
end
|
177
188
|
end
|
@@ -180,11 +191,23 @@ module Inch
|
|
180
191
|
"#<#{self.class.to_s}: #{path}>"
|
181
192
|
end
|
182
193
|
|
183
|
-
|
194
|
+
protected
|
184
195
|
|
185
196
|
def multi_code_examples?(text)
|
186
197
|
text.scan(/\b(#{Regexp.escape(name)})[^_0-9\!\?]/m).size > 1
|
187
198
|
end
|
199
|
+
|
200
|
+
def tag(name)
|
201
|
+
tags(name).first
|
202
|
+
end
|
203
|
+
|
204
|
+
def tags(name = nil)
|
205
|
+
object.tags(name)
|
206
|
+
rescue YARD::CodeObjects::ProxyMethodError
|
207
|
+
# this error is raised by YARD
|
208
|
+
# see broken.rb in test fixtures
|
209
|
+
[]
|
210
|
+
end
|
188
211
|
end
|
189
212
|
end
|
190
213
|
end
|
@@ -16,6 +16,20 @@ module Inch
|
|
16
16
|
name =~ /\!$/
|
17
17
|
end
|
18
18
|
|
19
|
+
def getter?
|
20
|
+
attr_info = object.attr_info || {}
|
21
|
+
read_info = attr_info[:read]
|
22
|
+
if read_info
|
23
|
+
read_info.path == path
|
24
|
+
else
|
25
|
+
parent.child(:"#{name}=")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def has_doc?
|
30
|
+
super && !implicit_docstring?
|
31
|
+
end
|
32
|
+
|
19
33
|
def has_parameters?
|
20
34
|
!parameters.empty?
|
21
35
|
end
|
@@ -68,6 +82,10 @@ module Inch
|
|
68
82
|
(return_tag && !return_tag.text.empty?) || docstring.describes_return?
|
69
83
|
end
|
70
84
|
|
85
|
+
def setter?
|
86
|
+
name =~ /\=$/ && parameters.size == 1
|
87
|
+
end
|
88
|
+
|
71
89
|
def questioning_name?
|
72
90
|
name =~ /\?$/
|
73
91
|
end
|
@@ -109,6 +127,17 @@ module Inch
|
|
109
127
|
lines.reverse
|
110
128
|
end
|
111
129
|
|
130
|
+
def implicit_docstring?
|
131
|
+
if getter?
|
132
|
+
docstring == "Returns the value of attribute #{name}"
|
133
|
+
elsif setter?
|
134
|
+
basename = name.to_s.gsub(/(\=)$/, '')
|
135
|
+
docstring == "Sets the attribute #{basename}"
|
136
|
+
else
|
137
|
+
false
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
112
141
|
def signature_parameter_names
|
113
142
|
object.parameters.map(&:first)
|
114
143
|
end
|
@@ -4,6 +4,12 @@ module Inch
|
|
4
4
|
# a namespace object can have methods and other namespace objects
|
5
5
|
# inside itself (e.g. classes and modules)
|
6
6
|
class NamespaceObject < Base
|
7
|
+
def child(name)
|
8
|
+
if children
|
9
|
+
children.detect { |child| child.name == name }
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
7
13
|
def children
|
8
14
|
object.children.map do |o|
|
9
15
|
Proxy.for(o)
|