reek 4.8.2 → 5.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/{samples/configuration/more_than_one_configuration_file/regular.reek → .reek.yml} +0 -0
- data/.rubocop.yml +17 -3
- data/.simplecov +1 -0
- data/.travis.yml +0 -5
- data/.yardopts +1 -1
- data/CHANGELOG.md +28 -0
- data/Gemfile +1 -1
- data/README.md +113 -98
- data/Rakefile +16 -3
- data/bin/reek +1 -3
- data/docs/API.md +2 -9
- data/docs/Basic-Smell-Options.md +51 -11
- data/docs/Code-Smells.md +1 -1
- data/docs/Command-Line-Options.md +14 -4
- data/docs/Duplicate-Method-Call.md +49 -1
- data/docs/Feature-Envy.md +44 -0
- data/docs/How-To-Write-New-Detectors.md +2 -3
- data/docs/{Prima-Donna-Method.md → Missing-Safe-Method.md} +11 -9
- data/docs/Rake-Task.md +1 -1
- data/docs/Reek-4-to-Reek-5-migration.md +193 -0
- data/docs/Reek-Driven-Development.md +1 -1
- data/docs/Uncommunicative-Method-Name.md +43 -4
- data/docs/Uncommunicative-Module-Name.md +48 -6
- data/docs/Uncommunicative-Parameter-Name.md +42 -4
- data/docs/Uncommunicative-Variable-Name.md +73 -2
- data/docs/Unused-Private-Method.md +1 -1
- data/docs/defaults.reek.yml +129 -0
- data/docs/yard_plugin.rb +1 -0
- data/features/command_line_interface/options.feature +46 -4
- data/features/command_line_interface/stdin.feature +27 -5
- data/features/configuration_files/accept_setting.feature +39 -22
- data/features/configuration_files/directory_specific_directives.feature +58 -53
- data/features/configuration_files/exclude_directives.feature +8 -7
- data/features/configuration_files/masking_smells.feature +35 -6
- data/features/configuration_files/mix_accept_reject_setting.feature +24 -21
- data/features/configuration_files/reject_setting.feature +45 -34
- data/features/configuration_files/schema_validation.feature +59 -0
- data/features/configuration_files/unused_private_method.feature +14 -12
- data/features/configuration_loading.feature +50 -7
- data/features/rake_task/rake_task.feature +5 -5
- data/features/reports/json.feature +4 -1
- data/features/reports/reports.feature +12 -12
- data/features/reports/yaml.feature +3 -0
- data/features/rspec_matcher.feature +9 -1
- data/features/step_definitions/reek_steps.rb +4 -0
- data/features/step_definitions/sample_file_steps.rb +9 -4
- data/features/support/env.rb +2 -2
- data/features/todo_list.feature +16 -13
- data/lib/reek/ast/node.rb +3 -6
- data/lib/reek/ast/object_refs.rb +1 -1
- data/lib/reek/ast/sexp_extensions/if.rb +1 -1
- data/lib/reek/ast/sexp_extensions/methods.rb +1 -1
- data/lib/reek/cli/application.rb +4 -3
- data/lib/reek/cli/command/report_command.rb +1 -2
- data/lib/reek/cli/command/todo_list_command.rb +4 -2
- data/lib/reek/cli/options.rb +27 -13
- data/lib/reek/cli/silencer.rb +14 -3
- data/lib/reek/code_comment.rb +14 -16
- data/lib/reek/configuration/app_configuration.rb +32 -28
- data/lib/reek/configuration/configuration_converter.rb +110 -0
- data/lib/reek/configuration/configuration_file_finder.rb +15 -40
- data/lib/reek/configuration/configuration_validator.rb +12 -23
- data/lib/reek/configuration/default_directive.rb +17 -3
- data/lib/reek/configuration/directory_directives.rb +17 -11
- data/lib/reek/configuration/excluded_paths.rb +1 -1
- data/lib/reek/configuration/rake_task_converter.rb +29 -0
- data/lib/reek/configuration/schema.yml +210 -0
- data/lib/reek/configuration/schema_validator.rb +38 -0
- data/lib/reek/context/attribute_context.rb +1 -1
- data/lib/reek/context/code_context.rb +4 -4
- data/lib/reek/context/method_context.rb +2 -2
- data/lib/reek/context/module_context.rb +1 -1
- data/lib/reek/context_builder.rb +9 -9
- data/lib/reek/detector_repository.rb +6 -0
- data/lib/reek/documentation_link.rb +2 -2
- data/lib/reek/errors/bad_detector_configuration_key_in_comment_error.rb +1 -1
- data/lib/reek/errors/bad_detector_in_comment_error.rb +1 -1
- data/lib/reek/errors/config_file_error.rb +11 -0
- data/lib/reek/errors/encoding_error.rb +2 -2
- data/lib/reek/errors/garbage_detector_configuration_in_comment_error.rb +1 -1
- data/lib/reek/errors/incomprehensible_source_error.rb +2 -2
- data/lib/reek/errors/syntax_error.rb +41 -0
- data/lib/reek/examiner.rb +9 -19
- data/lib/reek/rake/task.rb +3 -3
- data/lib/reek/report.rb +15 -10
- data/lib/reek/report/base_report.rb +8 -12
- data/lib/reek/report/code_climate/code_climate_configuration.yml +5 -9
- data/lib/reek/report/documentation_link_warning_formatter.rb +17 -0
- data/lib/reek/report/heading_formatter.rb +54 -0
- data/lib/reek/report/json_report.rb +1 -1
- data/lib/reek/report/location_formatter.rb +40 -0
- data/lib/reek/report/progress_formatter.rb +79 -0
- data/lib/reek/report/simple_warning_formatter.rb +34 -0
- data/lib/reek/report/text_report.rb +1 -2
- data/lib/reek/report/xml_report.rb +3 -3
- data/lib/reek/report/yaml_report.rb +1 -1
- data/lib/reek/smell_configuration.rb +2 -2
- data/lib/reek/smell_detectors.rb +1 -2
- data/lib/reek/smell_detectors/attribute.rb +0 -1
- data/lib/reek/smell_detectors/base_detector.rb +8 -11
- data/lib/reek/smell_detectors/boolean_parameter.rb +0 -1
- data/lib/reek/smell_detectors/class_variable.rb +0 -1
- data/lib/reek/smell_detectors/control_parameter.rb +17 -32
- data/lib/reek/smell_detectors/data_clump.rb +3 -4
- data/lib/reek/smell_detectors/duplicate_method_call.rb +5 -6
- data/lib/reek/smell_detectors/feature_envy.rb +0 -1
- data/lib/reek/smell_detectors/instance_variable_assumption.rb +0 -1
- data/lib/reek/smell_detectors/irresponsible_module.rb +0 -1
- data/lib/reek/smell_detectors/long_parameter_list.rb +1 -2
- data/lib/reek/smell_detectors/long_yield_list.rb +2 -3
- data/lib/reek/smell_detectors/manual_dispatch.rb +2 -2
- data/lib/reek/smell_detectors/{prima_donna_method.rb → missing_safe_method.rb} +6 -7
- data/lib/reek/smell_detectors/module_initialize.rb +0 -1
- data/lib/reek/smell_detectors/nested_iterators.rb +4 -5
- data/lib/reek/smell_detectors/nil_check.rb +0 -1
- data/lib/reek/smell_detectors/repeated_conditional.rb +3 -4
- data/lib/reek/smell_detectors/subclassed_from_core_class.rb +0 -1
- data/lib/reek/smell_detectors/too_many_constants.rb +1 -2
- data/lib/reek/smell_detectors/too_many_instance_variables.rb +1 -2
- data/lib/reek/smell_detectors/too_many_methods.rb +1 -2
- data/lib/reek/smell_detectors/too_many_statements.rb +1 -2
- data/lib/reek/smell_detectors/uncommunicative_method_name.rb +2 -3
- data/lib/reek/smell_detectors/uncommunicative_module_name.rb +2 -3
- data/lib/reek/smell_detectors/uncommunicative_parameter_name.rb +2 -3
- data/lib/reek/smell_detectors/uncommunicative_variable_name.rb +4 -5
- data/lib/reek/smell_detectors/unused_parameters.rb +0 -1
- data/lib/reek/smell_detectors/unused_private_method.rb +0 -1
- data/lib/reek/smell_detectors/utility_function.rb +1 -2
- data/lib/reek/smell_warning.rb +10 -8
- data/lib/reek/source/source_code.rb +40 -55
- data/lib/reek/source/source_locator.rb +7 -7
- data/lib/reek/spec.rb +6 -6
- data/lib/reek/spec/should_reek.rb +2 -2
- data/lib/reek/spec/should_reek_of.rb +9 -16
- data/lib/reek/spec/should_reek_only_of.rb +4 -4
- data/lib/reek/tree_dresser.rb +5 -5
- data/lib/reek/version.rb +1 -1
- data/reek.gemspec +3 -3
- data/samples/checkstyle.xml +1 -1
- data/samples/{clean.rb → clean_source/clean.rb} +0 -0
- data/samples/configuration/accepts_rejects_and_excludes_for_detectors.reek.yml +29 -0
- data/samples/configuration/accepts_rejects_and_excludes_for_directory_directives.reek.yml +30 -0
- data/samples/configuration/full_configuration.reek +8 -4
- data/samples/configuration/full_mask.reek +5 -4
- data/samples/{exceptions.reek → configuration/home/home.reek.yml} +0 -0
- data/samples/configuration/partial_mask.reek +3 -2
- data/samples/configuration/regular_configuration/.reek.yml +4 -0
- data/samples/configuration/{more_than_one_configuration_file/todo.reek → regular_configuration/empty_sub_directory/.gitignore} +0 -0
- data/samples/{configuration/single_configuration_file/.reek → no_config_file/.keep} +0 -0
- data/samples/paths.rb +5 -4
- data/samples/{inline.rb → smelly_source/inline.rb} +0 -0
- data/samples/{optparse.rb → smelly_source/optparse.rb} +0 -0
- data/samples/{redcloth.rb → smelly_source/redcloth.rb} +0 -0
- data/samples/{smelly.rb → smelly_source/smelly.rb} +0 -0
- data/samples/source_with_hidden_directories/.hidden/hidden.rb +1 -0
- data/samples/source_with_hidden_directories/not_hidden.rb +1 -0
- data/samples/{source_with_hidden_directories/uncommunicative_parameter_name.rb → source_with_non_ruby_files/ruby.rb} +0 -0
- data/spec/reek/ast/node_spec.rb +5 -5
- data/spec/reek/cli/application_spec.rb +18 -4
- data/spec/reek/cli/command/todo_list_command_spec.rb +4 -2
- data/spec/reek/cli/silencer_spec.rb +28 -0
- data/spec/reek/code_comment_spec.rb +0 -7
- data/spec/reek/configuration/app_configuration_spec.rb +44 -31
- data/spec/reek/configuration/configuration_file_finder_spec.rb +133 -49
- data/spec/reek/configuration/default_directive_spec.rb +1 -1
- data/spec/reek/configuration/directory_directives_spec.rb +3 -4
- data/spec/reek/configuration/excluded_paths_spec.rb +5 -5
- data/spec/reek/configuration/rake_task_converter_spec.rb +33 -0
- data/spec/reek/configuration/schema_validator_spec.rb +165 -0
- data/spec/reek/context/code_context_spec.rb +1 -1
- data/spec/reek/examiner_spec.rb +28 -1
- data/spec/reek/report/json_report_spec.rb +13 -46
- data/spec/reek/report/{formatter/location_formatter_spec.rb → location_formatter_spec.rb} +5 -5
- data/spec/reek/report/{formatter/progress_formatter_spec.rb → progress_formatter_spec.rb} +4 -4
- data/spec/reek/report/text_report_spec.rb +4 -4
- data/spec/reek/report/xml_report_spec.rb +1 -1
- data/spec/reek/report/yaml_report_spec.rb +9 -38
- data/spec/reek/report_spec.rb +3 -3
- data/spec/reek/smell_detectors/feature_envy_spec.rb +2 -2
- data/spec/reek/smell_detectors/{prima_donna_method_spec.rb → missing_safe_method_spec.rb} +9 -9
- data/spec/reek/smell_detectors/too_many_constants_spec.rb +3 -3
- data/spec/reek/smell_detectors/too_many_instance_variables_spec.rb +1 -1
- data/spec/reek/smell_detectors/uncommunicative_method_name_spec.rb +6 -6
- data/spec/reek/smell_detectors/uncommunicative_module_name_spec.rb +6 -4
- data/spec/reek/smell_detectors/uncommunicative_parameter_name_spec.rb +6 -4
- data/spec/reek/smell_detectors/uncommunicative_variable_name_spec.rb +6 -6
- data/spec/reek/smell_detectors/unused_private_method_spec.rb +1 -1
- data/spec/reek/smell_warning_spec.rb +4 -0
- data/spec/reek/source/source_code_spec.rb +16 -22
- data/spec/reek/source/source_locator_spec.rb +11 -11
- data/spec/reek/spec/should_reek_of_spec.rb +0 -4
- data/spec/reek/spec/should_reek_only_of_spec.rb +2 -2
- data/spec/reek/spec/should_reek_spec.rb +1 -1
- data/spec/reek/tree_dresser_spec.rb +2 -6
- data/spec/spec_helper.rb +3 -5
- data/tasks/configuration.rake +8 -5
- metadata +56 -35
- data/defaults.reek +0 -131
- data/features/configuration_files/warn_about_multiple_configuration_files.feature +0 -44
- data/lib/reek/report/formatter.rb +0 -33
- data/lib/reek/report/formatter/heading_formatter.rb +0 -52
- data/lib/reek/report/formatter/location_formatter.rb +0 -42
- data/lib/reek/report/formatter/progress_formatter.rb +0 -81
- data/lib/reek/report/formatter/simple_warning_formatter.rb +0 -35
- data/lib/reek/report/formatter/wiki_link_warning_formatter.rb +0 -23
- data/lib/reek/smell_detectors/syntax.rb +0 -37
- data/samples/configuration/non_public_modifiers_mask.reek +0 -3
- data/samples/smelly_with_inline_mask.rb +0 -8
- data/samples/smelly_with_modifiers.rb +0 -12
- data/samples/source_with_hidden_directories/.hidden/uncommunicative_method_name.rb +0 -5
- data/samples/source_with_non_ruby_files/uncommunicative_parameter_name.rb +0 -6
- data/spec/reek/smell_detectors/syntax_spec.rb +0 -17
@@ -16,7 +16,7 @@ module Reek
|
|
16
16
|
class LongParameterList < BaseDetector
|
17
17
|
# The name of the config field that sets the maximum number of
|
18
18
|
# parameters permitted in any method or block.
|
19
|
-
MAX_ALLOWED_PARAMS_KEY = 'max_params'
|
19
|
+
MAX_ALLOWED_PARAMS_KEY = 'max_params'
|
20
20
|
DEFAULT_MAX_ALLOWED_PARAMS = 3
|
21
21
|
|
22
22
|
def self.default_config
|
@@ -36,7 +36,6 @@ module Reek
|
|
36
36
|
count = expression.arg_names.length
|
37
37
|
return [] if count <= max_allowed_params
|
38
38
|
[smell_warning(
|
39
|
-
context: context,
|
40
39
|
lines: [source_line],
|
41
40
|
message: "has #{count} parameters",
|
42
41
|
parameters: { count: count })]
|
@@ -12,7 +12,7 @@ module Reek
|
|
12
12
|
class LongYieldList < BaseDetector
|
13
13
|
# The name of the config field that sets the maximum number of
|
14
14
|
# parameters permitted in any method or block.
|
15
|
-
MAX_ALLOWED_PARAMS_KEY = 'max_params'
|
15
|
+
MAX_ALLOWED_PARAMS_KEY = 'max_params'
|
16
16
|
DEFAULT_MAX_ALLOWED_PARAMS = 3
|
17
17
|
|
18
18
|
def self.default_config
|
@@ -24,14 +24,13 @@ module Reek
|
|
24
24
|
#
|
25
25
|
# @return [Array<SmellWarning>]
|
26
26
|
#
|
27
|
-
# :reek:DuplicateMethodCall
|
27
|
+
# @quality :reek:DuplicateMethodCall { max_calls: 2 }
|
28
28
|
def sniff
|
29
29
|
context.local_nodes(:yield).select do |yield_node|
|
30
30
|
yield_node.args.length > max_allowed_params
|
31
31
|
end.map do |yield_node|
|
32
32
|
count = yield_node.args.length
|
33
33
|
smell_warning(
|
34
|
-
context: context,
|
35
34
|
lines: [yield_node.line],
|
36
35
|
message: "yields #{count} parameters",
|
37
36
|
parameters: { count: count })
|
@@ -12,7 +12,7 @@ module Reek
|
|
12
12
|
#
|
13
13
|
# See {file:docs/Manual-Dispatch.md} for details.
|
14
14
|
class ManualDispatch < BaseDetector
|
15
|
-
MESSAGE = 'manually dispatches method call'
|
15
|
+
MESSAGE = 'manually dispatches method call'
|
16
16
|
|
17
17
|
#
|
18
18
|
# Checks for +respond_to?+ usage within the given method
|
@@ -23,7 +23,7 @@ module Reek
|
|
23
23
|
smelly_nodes = context.local_nodes(:send).select { |node| node.name == :respond_to? }
|
24
24
|
return [] if smelly_nodes.empty?
|
25
25
|
lines = smelly_nodes.map(&:line)
|
26
|
-
[smell_warning(
|
26
|
+
[smell_warning(lines: lines, message: MESSAGE)]
|
27
27
|
end
|
28
28
|
end
|
29
29
|
end
|
@@ -21,10 +21,10 @@ module Reek
|
|
21
21
|
# gets distorted and diluted, and ! ceases to convey any information
|
22
22
|
# whatsoever.
|
23
23
|
#
|
24
|
-
# Such a method is called
|
24
|
+
# Such a method is called MissingSafeMethod and is reported as a smell.
|
25
25
|
#
|
26
|
-
# See {file:docs/
|
27
|
-
class
|
26
|
+
# See {file:docs/Missing-Safe-Method.md} for details.
|
27
|
+
class MissingSafeMethod < BaseDetector
|
28
28
|
def self.contexts # :nodoc:
|
29
29
|
[:class]
|
30
30
|
end
|
@@ -48,20 +48,19 @@ module Reek
|
|
48
48
|
#
|
49
49
|
def sniff
|
50
50
|
context.node_instance_methods.select do |method_sexp|
|
51
|
-
|
51
|
+
missing_safe_method?(method_sexp)
|
52
52
|
end.map do |method_sexp|
|
53
53
|
name = method_sexp.name
|
54
54
|
smell_warning(
|
55
|
-
context: context,
|
56
55
|
lines: [method_sexp.line],
|
57
|
-
message: "has
|
56
|
+
message: "has missing safe method '#{name}'",
|
58
57
|
parameters: { name: name.to_s })
|
59
58
|
end
|
60
59
|
end
|
61
60
|
|
62
61
|
private
|
63
62
|
|
64
|
-
def
|
63
|
+
def missing_safe_method?(method_sexp)
|
65
64
|
return false unless method_sexp.ends_with_bang?
|
66
65
|
return false if ignore_method? method_sexp
|
67
66
|
return false if version_without_bang_exists? method_sexp
|
@@ -20,12 +20,12 @@ module Reek
|
|
20
20
|
|
21
21
|
# The name of the config field that sets the maximum depth
|
22
22
|
# of nested iterators to be permitted within any single method.
|
23
|
-
MAX_ALLOWED_NESTING_KEY = 'max_allowed_nesting'
|
23
|
+
MAX_ALLOWED_NESTING_KEY = 'max_allowed_nesting'
|
24
24
|
DEFAULT_MAX_ALLOWED_NESTING = 1
|
25
25
|
|
26
26
|
# The name of the config field that sets the names of any
|
27
27
|
# methods for which nesting should not be considered
|
28
|
-
IGNORE_ITERATORS_KEY = 'ignore_iterators'
|
28
|
+
IGNORE_ITERATORS_KEY = 'ignore_iterators'
|
29
29
|
DEFAULT_IGNORE_ITERATORS = ['tap'].freeze
|
30
30
|
|
31
31
|
def self.default_config
|
@@ -45,7 +45,6 @@ module Reek
|
|
45
45
|
find_violations.group_by(&:depth).map do |depth, group|
|
46
46
|
lines = group.map(&:line)
|
47
47
|
smell_warning(
|
48
|
-
context: context,
|
49
48
|
lines: lines,
|
50
49
|
message: "contains iterators nested #{depth} deep",
|
51
50
|
parameters: { depth: depth })
|
@@ -94,7 +93,7 @@ module Reek
|
|
94
93
|
#
|
95
94
|
# @return [Array<Iterator>]
|
96
95
|
#
|
97
|
-
# :reek:TooManyStatements
|
96
|
+
# @quality :reek:TooManyStatements { max_statements: 6 }
|
98
97
|
def scout(exp:, depth:)
|
99
98
|
return [] unless exp
|
100
99
|
# Find all non-nested blocks in this expression
|
@@ -126,7 +125,7 @@ module Reek
|
|
126
125
|
@max_allowed_nesting ||= value(MAX_ALLOWED_NESTING_KEY, context)
|
127
126
|
end
|
128
127
|
|
129
|
-
# :reek:FeatureEnvy
|
128
|
+
# @quality :reek:FeatureEnvy
|
130
129
|
def ignored_iterator?(exp)
|
131
130
|
ignore_iterators.any? { |pattern| /#{pattern}/ =~ exp.call.name } ||
|
132
131
|
exp.without_block_arguments?
|
@@ -28,7 +28,7 @@ module Reek
|
|
28
28
|
class RepeatedConditional < BaseDetector
|
29
29
|
# The name of the config field that sets the maximum number of
|
30
30
|
# identical conditionals permitted within any single class.
|
31
|
-
MAX_IDENTICAL_IFS_KEY = 'max_ifs'
|
31
|
+
MAX_IDENTICAL_IFS_KEY = 'max_ifs'
|
32
32
|
DEFAULT_MAX_IFS = 2
|
33
33
|
|
34
34
|
BLOCK_GIVEN_CONDITION = ::Parser::AST::Node.new(:send, [nil, :block_given?])
|
@@ -46,7 +46,7 @@ module Reek
|
|
46
46
|
#
|
47
47
|
# @return [Array<SmellWarning>]
|
48
48
|
#
|
49
|
-
# :reek:DuplicateMethodCall
|
49
|
+
# @quality :reek:DuplicateMethodCall { max_calls: 2 }
|
50
50
|
def sniff
|
51
51
|
conditional_counts.select do |_key, lines|
|
52
52
|
lines.length > max_identical_ifs
|
@@ -54,7 +54,6 @@ module Reek
|
|
54
54
|
occurs = lines.length
|
55
55
|
expression = key.format_to_ruby
|
56
56
|
smell_warning(
|
57
|
-
context: context,
|
58
57
|
lines: lines,
|
59
58
|
message: "tests '#{expression}' at least #{occurs} times",
|
60
59
|
parameters: { name: expression, count: occurs })
|
@@ -72,7 +71,7 @@ module Reek
|
|
72
71
|
# the given syntax tree together with the number of times each
|
73
72
|
# occurs. Ignores nested classes and modules.
|
74
73
|
#
|
75
|
-
# :reek:TooManyStatements
|
74
|
+
# @quality :reek:TooManyStatements { max_statements: 9 }
|
76
75
|
def conditional_counts
|
77
76
|
result = Hash.new { |hash, key| hash[key] = [] }
|
78
77
|
collector = proc do |node|
|
@@ -15,7 +15,7 @@ module Reek
|
|
15
15
|
class TooManyConstants < BaseDetector
|
16
16
|
# The name of the config field that sets the maximum number
|
17
17
|
# of constants permitted in a class.
|
18
|
-
MAX_ALLOWED_CONSTANTS_KEY = 'max_constants'
|
18
|
+
MAX_ALLOWED_CONSTANTS_KEY = 'max_constants'
|
19
19
|
DEFAULT_MAX_CONSTANTS = 5
|
20
20
|
IGNORED_NODES = [:module, :class].freeze
|
21
21
|
|
@@ -50,7 +50,6 @@ module Reek
|
|
50
50
|
|
51
51
|
def build_smell_warning(count)
|
52
52
|
[smell_warning(
|
53
|
-
context: context,
|
54
53
|
lines: [source_line],
|
55
54
|
message: "has #{count} constants",
|
56
55
|
parameters: { count: count })]
|
@@ -15,7 +15,7 @@ module Reek
|
|
15
15
|
class TooManyInstanceVariables < BaseDetector
|
16
16
|
# The name of the config field that sets the maximum number of instance
|
17
17
|
# variables permitted in a class.
|
18
|
-
MAX_ALLOWED_IVARS_KEY = 'max_instance_variables'
|
18
|
+
MAX_ALLOWED_IVARS_KEY = 'max_instance_variables'
|
19
19
|
DEFAULT_MAX_IVARS = 4
|
20
20
|
|
21
21
|
def self.contexts
|
@@ -38,7 +38,6 @@ module Reek
|
|
38
38
|
count = variables.uniq.size
|
39
39
|
return [] if count <= max_allowed_ivars
|
40
40
|
[smell_warning(
|
41
|
-
context: context,
|
42
41
|
lines: [source_line],
|
43
42
|
message: "has at least #{count} instance variables",
|
44
43
|
parameters: { count: count })]
|
@@ -17,7 +17,7 @@ module Reek
|
|
17
17
|
class TooManyMethods < BaseDetector
|
18
18
|
# The name of the config field that sets the maximum number of methods
|
19
19
|
# permitted in a class.
|
20
|
-
MAX_ALLOWED_METHODS_KEY = 'max_methods'
|
20
|
+
MAX_ALLOWED_METHODS_KEY = 'max_methods'
|
21
21
|
DEFAULT_MAX_METHODS = 15
|
22
22
|
|
23
23
|
def self.contexts
|
@@ -40,7 +40,6 @@ module Reek
|
|
40
40
|
actual = context.node_instance_methods.length
|
41
41
|
return [] if actual <= max_allowed_methods
|
42
42
|
[smell_warning(
|
43
|
-
context: context,
|
44
43
|
lines: [source_line],
|
45
44
|
message: "has at least #{actual} methods",
|
46
45
|
parameters: { count: actual })]
|
@@ -13,7 +13,7 @@ module Reek
|
|
13
13
|
class TooManyStatements < BaseDetector
|
14
14
|
# The name of the config field that sets the maximum number of
|
15
15
|
# statements permitted in any method.
|
16
|
-
MAX_ALLOWED_STATEMENTS_KEY = 'max_statements'
|
16
|
+
MAX_ALLOWED_STATEMENTS_KEY = 'max_statements'
|
17
17
|
DEFAULT_MAX_STATEMENTS = 5
|
18
18
|
|
19
19
|
def self.default_config
|
@@ -31,7 +31,6 @@ module Reek
|
|
31
31
|
count = context.number_of_statements
|
32
32
|
return [] if count <= max_allowed_statements
|
33
33
|
[smell_warning(
|
34
|
-
context: context,
|
35
34
|
lines: [source_line],
|
36
35
|
message: "has approx #{count} statements",
|
37
36
|
parameters: { count: count })]
|
@@ -20,8 +20,8 @@ module Reek
|
|
20
20
|
#
|
21
21
|
# See {file:docs/Uncommunicative-Method-Name.md} for details.
|
22
22
|
class UncommunicativeMethodName < BaseDetector
|
23
|
-
REJECT_KEY = 'reject'
|
24
|
-
ACCEPT_KEY = 'accept'
|
23
|
+
REJECT_KEY = 'reject'
|
24
|
+
ACCEPT_KEY = 'accept'
|
25
25
|
DEFAULT_REJECT_PATTERNS = [/^[a-z]$/, /[0-9]$/, /[A-Z]/].freeze
|
26
26
|
DEFAULT_ACCEPT_PATTERNS = [].freeze
|
27
27
|
|
@@ -41,7 +41,6 @@ module Reek
|
|
41
41
|
return [] if acceptable_name?(name)
|
42
42
|
|
43
43
|
[smell_warning(
|
44
|
-
context: context,
|
45
44
|
lines: [source_line],
|
46
45
|
message: "has the name '#{name}'",
|
47
46
|
parameters: { name: name })]
|
@@ -21,13 +21,13 @@ module Reek
|
|
21
21
|
class UncommunicativeModuleName < BaseDetector
|
22
22
|
# The name of the config field that lists the regexps of
|
23
23
|
# smelly names to be reported.
|
24
|
-
REJECT_KEY = 'reject'
|
24
|
+
REJECT_KEY = 'reject'
|
25
25
|
DEFAULT_REJECT_PATTERNS = [/^.$/, /[0-9]$/].freeze
|
26
26
|
|
27
27
|
# The name of the config field that lists the specific names that are
|
28
28
|
# to be treated as exceptions; these names will not be reported as
|
29
29
|
# uncommunicative.
|
30
|
-
ACCEPT_KEY = 'accept'
|
30
|
+
ACCEPT_KEY = 'accept'
|
31
31
|
DEFAULT_ACCEPT_PATTERNS = [].freeze
|
32
32
|
|
33
33
|
def self.default_config
|
@@ -53,7 +53,6 @@ module Reek
|
|
53
53
|
fully_qualified_name: fully_qualified_name)
|
54
54
|
|
55
55
|
[smell_warning(
|
56
|
-
context: context,
|
57
56
|
lines: [source_line],
|
58
57
|
message: "has the name '#{module_name}'",
|
59
58
|
parameters: { name: module_name })]
|
@@ -21,10 +21,10 @@ module Reek
|
|
21
21
|
#
|
22
22
|
# See {file:docs/Uncommunicative-Parameter-Name.md} for details.
|
23
23
|
class UncommunicativeParameterName < BaseDetector
|
24
|
-
REJECT_KEY = 'reject'
|
24
|
+
REJECT_KEY = 'reject'
|
25
25
|
DEFAULT_REJECT_PATTERNS = [/^.$/, /[0-9]$/, /[A-Z]/, /^_/].freeze
|
26
26
|
|
27
|
-
ACCEPT_KEY = 'accept'
|
27
|
+
ACCEPT_KEY = 'accept'
|
28
28
|
DEFAULT_ACCEPT_PATTERNS = [].freeze
|
29
29
|
|
30
30
|
def self.default_config
|
@@ -45,7 +45,6 @@ module Reek
|
|
45
45
|
|
46
46
|
params.map(&:name).map do |name|
|
47
47
|
smell_warning(
|
48
|
-
context: context,
|
49
48
|
lines: [source_line],
|
50
49
|
message: "has the parameter name '#{name}'",
|
51
50
|
parameters: { name: name.to_s })
|
@@ -24,7 +24,7 @@ module Reek
|
|
24
24
|
class UncommunicativeVariableName < BaseDetector
|
25
25
|
# The name of the config field that lists the regexps of
|
26
26
|
# smelly names to be reported.
|
27
|
-
REJECT_KEY = 'reject'
|
27
|
+
REJECT_KEY = 'reject'
|
28
28
|
DEFAULT_REJECT_SET = [
|
29
29
|
/^.$/, # single-character names
|
30
30
|
/[0-9]$/, # any name ending with a number
|
@@ -34,7 +34,7 @@ module Reek
|
|
34
34
|
# The name of the config field that lists the specific names that are
|
35
35
|
# to be treated as exceptions; these names will not be reported as
|
36
36
|
# uncommunicative.
|
37
|
-
ACCEPT_KEY = 'accept'
|
37
|
+
ACCEPT_KEY = 'accept'
|
38
38
|
DEFAULT_ACCEPT_SET = [/^_$/].freeze
|
39
39
|
|
40
40
|
def self.default_config
|
@@ -57,7 +57,6 @@ module Reek
|
|
57
57
|
uncommunicative_variable_name?(name)
|
58
58
|
end.map do |name, lines|
|
59
59
|
smell_warning(
|
60
|
-
context: context,
|
61
60
|
lines: lines,
|
62
61
|
message: "has the variable name '#{name}'",
|
63
62
|
parameters: { name: name.to_s })
|
@@ -102,7 +101,7 @@ module Reek
|
|
102
101
|
assignment_nodes.each { |asgn| accumulator[asgn.children.first].push(asgn.line) }
|
103
102
|
end
|
104
103
|
|
105
|
-
# :reek:TooManyStatements
|
104
|
+
# @quality :reek:TooManyStatements { max_statements: 6 }
|
106
105
|
def find_block_argument_variable_names(accumulator)
|
107
106
|
arg_search_exp = case expression.type
|
108
107
|
when :class, :module
|
@@ -130,7 +129,7 @@ module Reek
|
|
130
129
|
end
|
131
130
|
end
|
132
131
|
|
133
|
-
# :reek:UtilityFunction
|
132
|
+
# @quality :reek:UtilityFunction
|
134
133
|
def record_variable_name(exp, symbol, accumulator)
|
135
134
|
varname = symbol.to_s.sub(/^\*/, '')
|
136
135
|
return if varname == ''
|
@@ -38,7 +38,7 @@ module Reek
|
|
38
38
|
#
|
39
39
|
# See {file:docs/Utility-Function.md} for details.
|
40
40
|
class UtilityFunction < BaseDetector
|
41
|
-
PUBLIC_METHODS_ONLY_KEY = 'public_methods_only'
|
41
|
+
PUBLIC_METHODS_ONLY_KEY = 'public_methods_only'
|
42
42
|
PUBLIC_METHODS_ONLY_DEFAULT = false
|
43
43
|
|
44
44
|
def self.default_config
|
@@ -63,7 +63,6 @@ module Reek
|
|
63
63
|
return [] if ignore_method?
|
64
64
|
|
65
65
|
[smell_warning(
|
66
|
-
context: context,
|
67
66
|
lines: [source_line],
|
68
67
|
message: "doesn't depend on instance state (maybe move it to another class?)")]
|
69
68
|
end
|
data/lib/reek/smell_warning.rb
CHANGED
@@ -9,7 +9,7 @@ module Reek
|
|
9
9
|
#
|
10
10
|
# @public
|
11
11
|
#
|
12
|
-
# :reek:TooManyInstanceVariables
|
12
|
+
# @quality :reek:TooManyInstanceVariables { max_instance_variables: 6 }
|
13
13
|
class SmellWarning
|
14
14
|
include Comparable
|
15
15
|
extend Forwardable
|
@@ -22,7 +22,7 @@ module Reek
|
|
22
22
|
# objects yourself. This is why the initializer is not part of the
|
23
23
|
# public API.
|
24
24
|
#
|
25
|
-
# :reek:LongParameterList
|
25
|
+
# @quality :reek:LongParameterList { max_params: 6 }
|
26
26
|
def initialize(smell_detector, context: '', lines:, message:,
|
27
27
|
source:, parameters: {})
|
28
28
|
@smell_detector = smell_detector
|
@@ -56,7 +56,9 @@ module Reek
|
|
56
56
|
base_hash.merge(stringified_params)
|
57
57
|
end
|
58
58
|
|
59
|
-
|
59
|
+
def yaml_hash
|
60
|
+
to_hash.merge('documentation_link' => explanatory_link)
|
61
|
+
end
|
60
62
|
|
61
63
|
def base_message
|
62
64
|
"#{smell_type}: #{context} #{message}"
|
@@ -80,11 +82,11 @@ module Reek
|
|
80
82
|
|
81
83
|
def base_hash
|
82
84
|
{
|
83
|
-
'context'
|
84
|
-
'lines'
|
85
|
-
'message'
|
86
|
-
'smell_type'
|
87
|
-
'source'
|
85
|
+
'context' => context,
|
86
|
+
'lines' => lines,
|
87
|
+
'message' => message,
|
88
|
+
'smell_type' => smell_type,
|
89
|
+
'source' => source
|
88
90
|
}
|
89
91
|
end
|
90
92
|
end
|