reek 2.2.1 → 3.0.0
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/.travis.yml +9 -4
- data/CHANGELOG +8 -0
- data/Gemfile +6 -4
- data/README.md +6 -0
- data/docs/API.md +51 -22
- data/docs/Configuration-Files.md +12 -1
- data/docs/Feature-Envy.md +30 -10
- data/docs/How-reek-works-internally.md +109 -39
- data/docs/RSpec-matchers.md +26 -22
- data/docs/Reek-Driven-Development.md +0 -8
- data/docs/Utility-Function.md +8 -10
- data/features/{ruby_api/api.feature → command_line_interface/basic_usage.feature} +2 -2
- data/features/programmatic_access.feature +21 -2
- data/features/samples.feature +3 -1
- data/lib/reek.rb +2 -2
- data/lib/reek/{core → ast}/ast_node_class_map.rb +8 -8
- data/lib/reek/{sexp/sexp_node.rb → ast/node.rb} +47 -6
- data/lib/reek/{core → ast}/object_refs.rb +2 -1
- data/lib/reek/{core → ast}/reference_collector.rb +2 -1
- data/lib/reek/{sexp → ast}/sexp_extensions.rb +10 -5
- data/lib/reek/{sexp → ast}/sexp_formatter.rb +7 -5
- data/lib/reek/cli/application.rb +1 -0
- data/lib/reek/cli/command.rb +1 -0
- data/lib/reek/cli/input.rb +4 -1
- data/lib/reek/cli/option_interpreter.rb +6 -4
- data/lib/reek/cli/options.rb +2 -1
- data/lib/reek/cli/reek_command.rb +3 -2
- data/lib/reek/cli/silencer.rb +1 -0
- data/lib/reek/{core → cli}/warning_collector.rb +2 -1
- data/lib/reek/code_comment.rb +36 -0
- data/lib/reek/configuration/app_configuration.rb +17 -2
- data/lib/reek/configuration/configuration_file_finder.rb +1 -0
- data/lib/reek/{core → context}/code_context.rb +7 -5
- data/lib/reek/{core → context}/method_context.rb +5 -3
- data/lib/reek/{core → context}/module_context.rb +8 -3
- data/lib/reek/{core/stop_context.rb → context/root_context.rb} +4 -2
- data/lib/reek/{core → context}/singleton_method_context.rb +2 -1
- data/lib/reek/examiner.rb +82 -0
- data/lib/reek/report/formatter.rb +70 -0
- data/lib/reek/report/heading_formatter.rb +45 -0
- data/lib/reek/report/location_formatter.rb +35 -0
- data/lib/reek/report/report.rb +198 -0
- data/lib/reek/smells.rb +24 -13
- data/lib/reek/smells/attribute.rb +6 -4
- data/lib/reek/smells/boolean_parameter.rb +3 -1
- data/lib/reek/smells/class_variable.rb +3 -1
- data/lib/reek/smells/control_parameter.rb +3 -1
- data/lib/reek/smells/data_clump.rb +3 -1
- data/lib/reek/smells/duplicate_method_call.rb +3 -1
- data/lib/reek/smells/feature_envy.rb +3 -1
- data/lib/reek/smells/irresponsible_module.rb +12 -7
- data/lib/reek/smells/long_parameter_list.rb +5 -3
- data/lib/reek/smells/long_yield_list.rb +3 -1
- data/lib/reek/smells/module_initialize.rb +3 -1
- data/lib/reek/smells/nested_iterators.rb +3 -1
- data/lib/reek/smells/nil_check.rb +3 -1
- data/lib/reek/smells/prima_donna_method.rb +3 -1
- data/lib/reek/smells/repeated_conditional.rb +5 -3
- data/lib/reek/{core → smells}/smell_configuration.rb +3 -1
- data/lib/reek/smells/smell_detector.rb +9 -7
- data/lib/reek/{core → smells}/smell_repository.rb +3 -2
- data/lib/reek/smells/smell_warning.rb +6 -4
- data/lib/reek/smells/too_many_instance_variables.rb +3 -1
- data/lib/reek/smells/too_many_methods.rb +3 -1
- data/lib/reek/smells/too_many_statements.rb +3 -1
- data/lib/reek/smells/uncommunicative_method_name.rb +3 -1
- data/lib/reek/smells/uncommunicative_module_name.rb +3 -1
- data/lib/reek/smells/uncommunicative_parameter_name.rb +3 -1
- data/lib/reek/smells/uncommunicative_variable_name.rb +3 -1
- data/lib/reek/smells/unused_parameters.rb +3 -1
- data/lib/reek/smells/utility_function.rb +5 -2
- data/lib/reek/source/source_code.rb +40 -9
- data/lib/reek/source/source_locator.rb +30 -12
- data/lib/reek/spec/should_reek.rb +5 -4
- data/lib/reek/spec/should_reek_of.rb +3 -2
- data/lib/reek/spec/should_reek_only_of.rb +5 -4
- data/lib/reek/tree_dresser.rb +32 -0
- data/lib/reek/tree_walker.rb +182 -0
- data/lib/reek/version.rb +1 -1
- data/reek.gemspec +3 -3
- data/spec/factories/factories.rb +2 -0
- data/spec/reek/{sexp/sexp_node_spec.rb → ast/node_spec.rb} +2 -2
- data/spec/reek/{core → ast}/object_refs_spec.rb +3 -3
- data/spec/reek/{core → ast}/reference_collector_spec.rb +2 -2
- data/spec/reek/{sexp → ast}/sexp_extensions_spec.rb +6 -16
- data/spec/reek/{sexp → ast}/sexp_formatter_spec.rb +2 -2
- data/spec/reek/cli/option_interpreter_spec.rb +2 -1
- data/spec/reek/{core → cli}/warning_collector_spec.rb +3 -3
- data/spec/reek/{core/code_comment_spec.rb → code_comment_spec.rb} +3 -3
- data/spec/reek/configuration/app_configuration_spec.rb +31 -18
- data/spec/reek/{core → context}/code_context_spec.rb +14 -15
- data/spec/reek/{core → context}/method_context_spec.rb +8 -8
- data/spec/reek/{core → context}/module_context_spec.rb +4 -4
- data/spec/reek/context/root_context_spec.rb +14 -0
- data/spec/reek/{core → context}/singleton_method_context_spec.rb +4 -4
- data/spec/reek/{core/examiner_spec.rb → examiner_spec.rb} +3 -42
- data/spec/reek/{cli → report}/html_report_spec.rb +5 -5
- data/spec/reek/report/json_report_spec.rb +20 -0
- data/spec/reek/{cli → report}/text_report_spec.rb +14 -14
- data/spec/reek/{cli → report}/xml_report_spec.rb +7 -7
- data/spec/reek/report/yaml_report_spec.rb +20 -0
- data/spec/reek/smells/attribute_spec.rb +2 -1
- data/spec/reek/smells/boolean_parameter_spec.rb +1 -1
- data/spec/reek/smells/class_variable_spec.rb +5 -5
- data/spec/reek/smells/control_parameter_spec.rb +1 -1
- data/spec/reek/smells/data_clump_spec.rb +1 -1
- data/spec/reek/smells/duplicate_method_call_spec.rb +3 -3
- data/spec/reek/smells/feature_envy_spec.rb +1 -1
- data/spec/reek/smells/irresponsible_module_spec.rb +24 -28
- data/spec/reek/smells/long_parameter_list_spec.rb +2 -2
- data/spec/reek/smells/long_yield_list_spec.rb +2 -2
- data/spec/reek/smells/nested_iterators_spec.rb +1 -1
- data/spec/reek/smells/nil_check_spec.rb +2 -2
- data/spec/reek/smells/prima_donna_method_spec.rb +3 -3
- data/spec/reek/smells/repeated_conditional_spec.rb +6 -6
- data/spec/reek/{core → smells}/smell_configuration_spec.rb +4 -4
- data/spec/reek/smells/smell_detector_shared.rb +2 -2
- data/spec/reek/{core → smells}/smell_repository_spec.rb +5 -4
- data/spec/reek/smells/too_many_instance_variables_spec.rb +1 -1
- data/spec/reek/smells/too_many_methods_spec.rb +4 -4
- data/spec/reek/smells/too_many_statements_spec.rb +2 -2
- data/spec/reek/smells/uncommunicative_method_name_spec.rb +1 -1
- data/spec/reek/smells/uncommunicative_module_name_spec.rb +4 -4
- data/spec/reek/smells/uncommunicative_parameter_name_spec.rb +2 -2
- data/spec/reek/smells/uncommunicative_variable_name_spec.rb +3 -3
- data/spec/reek/smells/utility_function_spec.rb +23 -1
- data/spec/reek/source/source_code_spec.rb +1 -1
- data/spec/reek/source/source_locator_spec.rb +30 -0
- data/spec/reek/spec/should_reek_of_spec.rb +0 -17
- data/spec/reek/spec/should_reek_spec.rb +0 -25
- data/spec/reek/tree_dresser_spec.rb +16 -0
- data/spec/reek/{core/tree_walker_spec.rb → tree_walker_spec.rb} +5 -5
- data/spec/samples/{simple_configuration.reek → configuration/simple_configuration.reek} +0 -0
- data/spec/samples/configuration/with_excluded_paths.reek +4 -0
- data/spec/samples/source_with_exclude_paths/ignore_me/uncommunicative_method_name.rb +5 -0
- data/spec/samples/source_with_exclude_paths/nested/ignore_me_as_well/irresponsible_module.rb +2 -0
- data/spec/samples/source_with_exclude_paths/nested/uncommunicative_parameter_name.rb +6 -0
- data/spec/spec_helper.rb +6 -7
- data/tasks/develop.rake +2 -2
- metadata +71 -69
- data/lib/reek/cli/report/formatter.rb +0 -69
- data/lib/reek/cli/report/heading_formatter.rb +0 -45
- data/lib/reek/cli/report/location_formatter.rb +0 -34
- data/lib/reek/cli/report/report.rb +0 -191
- data/lib/reek/core/ast_node.rb +0 -38
- data/lib/reek/core/code_comment.rb +0 -37
- data/lib/reek/core/examiner.rb +0 -85
- data/lib/reek/core/tree_dresser.rb +0 -24
- data/lib/reek/core/tree_walker.rb +0 -180
- data/lib/reek/source/source_repository.rb +0 -43
- data/spec/reek/cli/json_report_spec.rb +0 -20
- data/spec/reek/cli/yaml_report_spec.rb +0 -20
- data/spec/reek/core/object_source_spec.rb +0 -18
- data/spec/reek/core/stop_context_spec.rb +0 -14
- data/spec/reek/core/tree_dresser_spec.rb +0 -16
@@ -0,0 +1,198 @@
|
|
1
|
+
require 'rainbow'
|
2
|
+
require 'json'
|
3
|
+
require_relative 'formatter'
|
4
|
+
require_relative 'heading_formatter'
|
5
|
+
|
6
|
+
module Reek
|
7
|
+
module Report
|
8
|
+
#
|
9
|
+
# A report that contains the smells and smell counts following source code analysis.
|
10
|
+
#
|
11
|
+
# @abstract Subclass and override {#show} to create a concrete report class.
|
12
|
+
class Base
|
13
|
+
# @api private
|
14
|
+
NO_WARNINGS_COLOR = :green
|
15
|
+
# @api private
|
16
|
+
WARNINGS_COLOR = :red
|
17
|
+
|
18
|
+
def initialize(options = {})
|
19
|
+
@examiners = []
|
20
|
+
@total_smell_count = 0
|
21
|
+
@options = options
|
22
|
+
@warning_formatter = options.fetch :warning_formatter, SimpleWarningFormatter.new
|
23
|
+
@report_formatter = options.fetch :report_formatter, Formatter
|
24
|
+
@sort_by_issue_count = options.fetch :sort_by_issue_count, false
|
25
|
+
end
|
26
|
+
|
27
|
+
# Add Examiner to report on. The report will output results for all
|
28
|
+
# added examiners.
|
29
|
+
#
|
30
|
+
# @param [Reek::Examiner] examiner object to report on
|
31
|
+
def add_examiner(examiner)
|
32
|
+
@total_smell_count += examiner.smells_count
|
33
|
+
@examiners << examiner
|
34
|
+
self
|
35
|
+
end
|
36
|
+
|
37
|
+
# Render the report results on STDOUT
|
38
|
+
def show
|
39
|
+
raise NotImplementedError
|
40
|
+
end
|
41
|
+
|
42
|
+
# @api private
|
43
|
+
def smells?
|
44
|
+
@total_smell_count > 0
|
45
|
+
end
|
46
|
+
|
47
|
+
# @api private
|
48
|
+
def smells
|
49
|
+
@examiners.map(&:smells).flatten
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
#
|
54
|
+
# Generates a sorted, text summary of smells in examiners
|
55
|
+
#
|
56
|
+
class TextReport < Base
|
57
|
+
def show
|
58
|
+
sort_examiners if smells?
|
59
|
+
display_summary
|
60
|
+
display_total_smell_count
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def smell_summaries
|
66
|
+
@examiners.map { |ex| summarize_single_examiner(ex) }.reject(&:empty?)
|
67
|
+
end
|
68
|
+
|
69
|
+
def display_summary
|
70
|
+
smell_summaries.each { |smell| puts smell }
|
71
|
+
end
|
72
|
+
|
73
|
+
def display_total_smell_count
|
74
|
+
return unless @examiners.size > 1
|
75
|
+
print total_smell_count_message
|
76
|
+
end
|
77
|
+
|
78
|
+
def summarize_single_examiner(examiner)
|
79
|
+
result = heading_formatter.header(examiner)
|
80
|
+
if examiner.smelly?
|
81
|
+
formatted_list = @report_formatter.format_list(examiner.smells,
|
82
|
+
@warning_formatter)
|
83
|
+
result += ":\n#{formatted_list}"
|
84
|
+
end
|
85
|
+
result
|
86
|
+
end
|
87
|
+
|
88
|
+
def sort_examiners
|
89
|
+
@examiners.sort_by!(&:smells_count).reverse! if @sort_by_issue_count
|
90
|
+
end
|
91
|
+
|
92
|
+
def total_smell_count_message
|
93
|
+
colour = smells? ? WARNINGS_COLOR : NO_WARNINGS_COLOR
|
94
|
+
s = @total_smell_count == 1 ? '' : 's'
|
95
|
+
Rainbow("#{@total_smell_count} total warning#{s}\n").color(colour)
|
96
|
+
end
|
97
|
+
|
98
|
+
def heading_formatter
|
99
|
+
@heading_formatter ||=
|
100
|
+
@options.fetch(:heading_formatter, HeadingFormatter::Quiet).new(@report_formatter)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
#
|
105
|
+
# Displays a list of smells in YAML format
|
106
|
+
# YAML with empty array for 0 smells
|
107
|
+
class YAMLReport < Base
|
108
|
+
def show
|
109
|
+
print smells.map(&:yaml_hash).to_yaml
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
#
|
114
|
+
# Displays a list of smells in JSON format
|
115
|
+
# JSON with empty array for 0 smells
|
116
|
+
class JSONReport < Base
|
117
|
+
def show
|
118
|
+
print ::JSON.generate(
|
119
|
+
smells.map do |smell|
|
120
|
+
smell.yaml_hash(@warning_formatter)
|
121
|
+
end
|
122
|
+
)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
#
|
127
|
+
# Saves the report as a HTML file
|
128
|
+
#
|
129
|
+
class HTMLReport < Base
|
130
|
+
require 'erb'
|
131
|
+
|
132
|
+
def show
|
133
|
+
path = File.expand_path('../../../../assets/html_output.html.erb',
|
134
|
+
__FILE__)
|
135
|
+
File.open('reek.html', 'w+') do |file|
|
136
|
+
file.puts ERB.new(File.read(path)).result(binding)
|
137
|
+
end
|
138
|
+
print("Html file saved\n")
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
#
|
143
|
+
# Generates a list of smells in XML format
|
144
|
+
#
|
145
|
+
class XMLReport < Base
|
146
|
+
require 'rexml/document'
|
147
|
+
|
148
|
+
def show
|
149
|
+
checkstyle = REXML::Element.new('checkstyle', document)
|
150
|
+
|
151
|
+
smells.group_by(&:source).each do |file, file_smells|
|
152
|
+
file_to_xml(file, file_smells, checkstyle)
|
153
|
+
end
|
154
|
+
|
155
|
+
print_xml(checkstyle.parent)
|
156
|
+
end
|
157
|
+
|
158
|
+
private
|
159
|
+
|
160
|
+
def document
|
161
|
+
REXML::Document.new.tap do |doc|
|
162
|
+
doc << REXML::XMLDecl.new
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def file_to_xml(file, file_smells, parent)
|
167
|
+
REXML::Element.new('file', parent).tap do |element|
|
168
|
+
element.attributes['name'] = File.realpath(file)
|
169
|
+
smells_to_xml(file_smells, element)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def smells_to_xml(smells, parent)
|
174
|
+
smells.each do |smell|
|
175
|
+
smell_to_xml(smell, parent)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def smell_to_xml(smell, parent)
|
180
|
+
REXML::Element.new('error', parent).tap do |element|
|
181
|
+
attributes = [
|
182
|
+
['line', smell.lines.first],
|
183
|
+
['column', 0],
|
184
|
+
['severity', 'warning'],
|
185
|
+
['message', smell.message],
|
186
|
+
['source', smell.smell_type]
|
187
|
+
]
|
188
|
+
element.add_attributes(attributes)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
def print_xml(document)
|
193
|
+
formatter = REXML::Formatters::Default.new
|
194
|
+
puts formatter.write(document, '')
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
data/lib/reek/smells.rb
CHANGED
@@ -1,13 +1,24 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
1
|
+
require_relative 'smells/attribute'
|
2
|
+
require_relative 'smells/boolean_parameter'
|
3
|
+
require_relative 'smells/class_variable'
|
4
|
+
require_relative 'smells/control_parameter'
|
5
|
+
require_relative 'smells/data_clump'
|
6
|
+
require_relative 'smells/duplicate_method_call'
|
7
|
+
require_relative 'smells/feature_envy'
|
8
|
+
require_relative 'smells/irresponsible_module'
|
9
|
+
require_relative 'smells/long_parameter_list'
|
10
|
+
require_relative 'smells/long_yield_list'
|
11
|
+
require_relative 'smells/module_initialize'
|
12
|
+
require_relative 'smells/nested_iterators'
|
13
|
+
require_relative 'smells/nil_check'
|
14
|
+
require_relative 'smells/prima_donna_method'
|
15
|
+
require_relative 'smells/repeated_conditional'
|
16
|
+
require_relative 'smells/too_many_instance_variables'
|
17
|
+
require_relative 'smells/too_many_methods'
|
18
|
+
require_relative 'smells/too_many_statements'
|
19
|
+
require_relative 'smells/uncommunicative_method_name'
|
20
|
+
require_relative 'smells/uncommunicative_module_name'
|
21
|
+
require_relative 'smells/uncommunicative_parameter_name'
|
22
|
+
require_relative 'smells/uncommunicative_variable_name'
|
23
|
+
require_relative 'smells/unused_parameters'
|
24
|
+
require_relative 'smells/utility_function'
|
@@ -1,5 +1,6 @@
|
|
1
|
+
require_relative 'smell_configuration'
|
1
2
|
require_relative 'smell_detector'
|
2
|
-
require_relative '
|
3
|
+
require_relative 'smell_warning'
|
3
4
|
|
4
5
|
module Reek
|
5
6
|
module Smells
|
@@ -12,9 +13,10 @@ module Reek
|
|
12
13
|
# +attr_reader+, +attr_writer+ and +attr_accessor+ -- including those
|
13
14
|
# that are private.
|
14
15
|
#
|
15
|
-
#
|
16
|
-
#
|
16
|
+
# See {file:docs/Attribute.md} for details.
|
17
|
+
# @api private
|
17
18
|
#
|
19
|
+
# TODO: Catch attributes declared "by hand"
|
18
20
|
class Attribute < SmellDetector
|
19
21
|
ATTR_DEFN_METHODS = [:attr, :attr_reader, :attr_writer, :attr_accessor]
|
20
22
|
VISIBILITY_MODIFIERS = [:private, :public, :protected]
|
@@ -31,7 +33,7 @@ module Reek
|
|
31
33
|
end
|
32
34
|
|
33
35
|
def self.default_config
|
34
|
-
super.merge(
|
36
|
+
super.merge(SmellConfiguration::ENABLED_KEY => false)
|
35
37
|
end
|
36
38
|
|
37
39
|
#
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require_relative 'smell_detector'
|
2
|
+
require_relative 'smell_warning'
|
2
3
|
|
3
4
|
module Reek
|
4
5
|
module Smells
|
@@ -10,7 +11,8 @@ module Reek
|
|
10
11
|
# Currently Reek can only detect a Boolean parameter when it has a
|
11
12
|
# default initializer.
|
12
13
|
#
|
13
|
-
# See docs/Boolean-Parameter for details.
|
14
|
+
# See {file:docs/Boolean-Parameter.md} for details.
|
15
|
+
# @api private
|
14
16
|
class BooleanParameter < SmellDetector
|
15
17
|
def self.smell_category
|
16
18
|
'ControlCouple'
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'set'
|
2
2
|
require_relative 'smell_detector'
|
3
|
+
require_relative 'smell_warning'
|
3
4
|
|
4
5
|
module Reek
|
5
6
|
module Smells
|
@@ -11,7 +12,8 @@ module Reek
|
|
11
12
|
# In particular, class variables can make it hard to set up tests (because
|
12
13
|
# the context of the test includes all global state).
|
13
14
|
#
|
14
|
-
# See docs/Class-Variable for details.
|
15
|
+
# See {file:docs/Class-Variable.md} for details.
|
16
|
+
# @api private
|
15
17
|
class ClassVariable < SmellDetector
|
16
18
|
def self.contexts # :nodoc:
|
17
19
|
[:class, :module]
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require_relative 'smell_detector'
|
2
|
+
require_relative 'smell_warning'
|
2
3
|
|
3
4
|
module Reek
|
4
5
|
module Smells
|
@@ -39,7 +40,8 @@ module Reek
|
|
39
40
|
# that remains next to where the caller invokes it in
|
40
41
|
# the source code.
|
41
42
|
#
|
42
|
-
# See docs/Control-Parameter for details.
|
43
|
+
# See {file:docs/Control-Parameter.md} for details.
|
44
|
+
# @api private
|
43
45
|
class ControlParameter < SmellDetector
|
44
46
|
def self.smell_category
|
45
47
|
'ControlCouple'
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require_relative 'smell_detector'
|
2
|
+
require_relative 'smell_warning'
|
2
3
|
|
3
4
|
module Reek
|
4
5
|
module Smells
|
@@ -14,7 +15,8 @@ module Reek
|
|
14
15
|
# Currently Reek looks for a group of two or more parameters with
|
15
16
|
# the same names that are expected by three or more methods of a class.
|
16
17
|
#
|
17
|
-
# See docs/Data-Clump for details.
|
18
|
+
# See {file:docs/Data-Clump.md} for details.
|
19
|
+
# @api private
|
18
20
|
class DataClump < SmellDetector
|
19
21
|
#
|
20
22
|
# The name of the config field that sets the maximum allowed
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require_relative 'smell_detector'
|
2
|
+
require_relative 'smell_warning'
|
2
3
|
|
3
4
|
module Reek
|
4
5
|
module Smells
|
@@ -15,7 +16,8 @@ module Reek
|
|
15
16
|
# @other.thing + @other.thing
|
16
17
|
# end
|
17
18
|
#
|
18
|
-
# See docs/Duplicate-Method-Call for details.
|
19
|
+
# See {file:docs/Duplicate-Method-Call.md} for details.
|
20
|
+
# @api private
|
19
21
|
class DuplicateMethodCall < SmellDetector
|
20
22
|
# The name of the config field that sets the maximum number of
|
21
23
|
# identical calls to be permitted within any single method.
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require_relative 'smell_detector'
|
2
|
+
require_relative 'smell_warning'
|
2
3
|
|
3
4
|
module Reek
|
4
5
|
module Smells
|
@@ -32,7 +33,8 @@ module Reek
|
|
32
33
|
# If the method doesn't reference self at all, +UtilityFunction+ is
|
33
34
|
# reported instead.
|
34
35
|
#
|
35
|
-
# See docs/Feature-Envy for details.
|
36
|
+
# See {file:docs/Feature-Envy.md} for details.
|
37
|
+
# @api private
|
36
38
|
class FeatureEnvy < SmellDetector
|
37
39
|
def self.smell_category
|
38
40
|
'LowCohesion'
|
@@ -1,5 +1,5 @@
|
|
1
1
|
require_relative 'smell_detector'
|
2
|
-
require_relative '
|
2
|
+
require_relative 'smell_warning'
|
3
3
|
|
4
4
|
module Reek
|
5
5
|
module Smells
|
@@ -7,13 +7,14 @@ module Reek
|
|
7
7
|
# It is considered good practice to annotate every class and module
|
8
8
|
# with a brief comment outlining its responsibilities.
|
9
9
|
#
|
10
|
-
# See docs/Irresponsible-Module for details.
|
10
|
+
# See {file:docs/Irresponsible-Module.md} for details.
|
11
|
+
# @api private
|
11
12
|
class IrresponsibleModule < SmellDetector
|
12
13
|
def self.contexts # :nodoc:
|
13
14
|
[:class]
|
14
15
|
end
|
15
16
|
|
16
|
-
def
|
17
|
+
def descriptive # :nodoc:
|
17
18
|
@descriptive ||= {}
|
18
19
|
end
|
19
20
|
|
@@ -23,13 +24,17 @@ module Reek
|
|
23
24
|
# @return [Array<SmellWarning>]
|
24
25
|
#
|
25
26
|
def examine_context(ctx)
|
26
|
-
|
27
|
-
|
27
|
+
return [] if descriptive?(ctx)
|
28
|
+
expression = ctx.exp
|
28
29
|
[SmellWarning.new(self,
|
29
30
|
context: ctx.full_name,
|
30
|
-
lines: [
|
31
|
+
lines: [expression.line],
|
31
32
|
message: 'has no descriptive comment',
|
32
|
-
parameters: { name:
|
33
|
+
parameters: { name: expression.text_name })]
|
34
|
+
end
|
35
|
+
|
36
|
+
def descriptive?(ctx)
|
37
|
+
descriptive[ctx.full_name] ||= ctx.descriptively_commented?
|
33
38
|
end
|
34
39
|
end
|
35
40
|
end
|
@@ -1,5 +1,6 @@
|
|
1
|
+
require_relative 'smell_configuration'
|
1
2
|
require_relative 'smell_detector'
|
2
|
-
require_relative '
|
3
|
+
require_relative 'smell_warning'
|
3
4
|
|
4
5
|
module Reek
|
5
6
|
module Smells
|
@@ -11,7 +12,8 @@ module Reek
|
|
11
12
|
# Currently +LongParameterList+ reports any method or block with too
|
12
13
|
# many parameters.
|
13
14
|
#
|
14
|
-
# See docs/Long-Parameter-List for details.
|
15
|
+
# See {file:docs/Long-Parameter-List.md} for details.
|
16
|
+
# @api private
|
15
17
|
class LongParameterList < SmellDetector
|
16
18
|
# The name of the config field that sets the maximum number of
|
17
19
|
# parameters permitted in any method or block.
|
@@ -21,7 +23,7 @@ module Reek
|
|
21
23
|
def self.default_config
|
22
24
|
super.merge(
|
23
25
|
MAX_ALLOWED_PARAMS_KEY => DEFAULT_MAX_ALLOWED_PARAMS,
|
24
|
-
|
26
|
+
SmellConfiguration::OVERRIDES_KEY => {
|
25
27
|
'initialize' => { MAX_ALLOWED_PARAMS_KEY => 5 }
|
26
28
|
}
|
27
29
|
)
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require_relative 'smell_detector'
|
2
|
+
require_relative 'smell_warning'
|
2
3
|
|
3
4
|
module Reek
|
4
5
|
module Smells
|
@@ -6,7 +7,8 @@ module Reek
|
|
6
7
|
# A variant on LongParameterList that checks the number of items
|
7
8
|
# passed to a block by a +yield+ call.
|
8
9
|
#
|
9
|
-
# See docs/Long-Yield-List for details.
|
10
|
+
# See {file:docs/Long-Yield-List.md} for details.
|
11
|
+
# @api private
|
10
12
|
class LongYieldList < SmellDetector
|
11
13
|
# The name of the config field that sets the maximum number of
|
12
14
|
# parameters permitted in any method or block.
|