reek 2.2.1 → 3.0.0
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/.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
@@ -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
|
@@ -7,7 +8,8 @@ module Reek
|
|
7
8
|
# hard to tell initialization order and parameters so having 'initialize'
|
8
9
|
# in a module is usually a bad idea
|
9
10
|
#
|
10
|
-
# See docs/Module-Initialize for details.
|
11
|
+
# See {file:docs/Module-Initialize.md} for details.
|
12
|
+
# @api private
|
11
13
|
class ModuleInitialize < SmellDetector
|
12
14
|
def self.contexts # :nodoc:
|
13
15
|
[: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
|
@@ -7,7 +8,8 @@ module Reek
|
|
7
8
|
#
|
8
9
|
# +NestedIterators+ reports failing methods only once.
|
9
10
|
#
|
10
|
-
# See docs/Nested-Iterators for details.
|
11
|
+
# See {file:docs/Nested-Iterators.md} for details.
|
12
|
+
# @api private
|
11
13
|
class NestedIterators < SmellDetector
|
12
14
|
# The name of the config field that sets the maximum depth
|
13
15
|
# of nested iterators to be permitted within any single method.
|
@@ -1,11 +1,13 @@
|
|
1
1
|
require_relative 'smell_detector'
|
2
|
+
require_relative 'smell_warning'
|
2
3
|
|
3
4
|
module Reek
|
4
5
|
module Smells
|
5
6
|
# Checking for nil is a special kind of type check, and therefore a case of
|
6
7
|
# SimulatedPolymorphism.
|
7
8
|
#
|
8
|
-
# See docs/Nil-Check for details.
|
9
|
+
# See {file:docs/Nil-Check.md} for details.
|
10
|
+
# @api private
|
9
11
|
class NilCheck < SmellDetector
|
10
12
|
def self.smell_category
|
11
13
|
'SimulatedPolymorphism'
|
@@ -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
|
@@ -21,7 +22,8 @@ module Reek
|
|
21
22
|
#
|
22
23
|
# Such a method is called PrimaDonnaMethod and is reported as a smell.
|
23
24
|
#
|
24
|
-
# See docs/Prima-Donna-Method for details.
|
25
|
+
# See {file:docs/Prima-Donna-Method.md} for details.
|
26
|
+
# @api private
|
25
27
|
class PrimaDonnaMethod < SmellDetector
|
26
28
|
def self.contexts # :nodoc:
|
27
29
|
[:class]
|
@@ -1,5 +1,6 @@
|
|
1
|
+
require_relative '../ast/node'
|
1
2
|
require_relative 'smell_detector'
|
2
|
-
require_relative '
|
3
|
+
require_relative 'smell_warning'
|
3
4
|
|
4
5
|
module Reek
|
5
6
|
module Smells
|
@@ -22,7 +23,8 @@ module Reek
|
|
22
23
|
# +RepeatedConditional+ checks for multiple conditionals
|
23
24
|
# testing the same value throughout a single class.
|
24
25
|
#
|
25
|
-
# See docs/Repeated-Conditional for details.
|
26
|
+
# See {file:docs/Repeated-Conditional.md} for details.
|
27
|
+
# @api private
|
26
28
|
class RepeatedConditional < SmellDetector
|
27
29
|
# The name of the config field that sets the maximum number of
|
28
30
|
# identical conditionals permitted within any single class.
|
@@ -33,7 +35,7 @@ module Reek
|
|
33
35
|
'SimulatedPolymorphism'
|
34
36
|
end
|
35
37
|
|
36
|
-
BLOCK_GIVEN_CONDITION = AST::Node.new(:send, [nil, :block_given?])
|
38
|
+
BLOCK_GIVEN_CONDITION = ::Parser::AST::Node.new(:send, [nil, :block_given?])
|
37
39
|
|
38
40
|
def self.contexts # :nodoc:
|
39
41
|
[:class]
|
@@ -1,8 +1,9 @@
|
|
1
1
|
module Reek
|
2
|
-
module
|
2
|
+
module Smells
|
3
3
|
#
|
4
4
|
# Represents a single set of configuration options for a smell detector
|
5
5
|
#
|
6
|
+
# @api private
|
6
7
|
class SmellConfiguration
|
7
8
|
# The name of the config field that specifies whether a smell is
|
8
9
|
# enabled. Set to +true+ or +false+.
|
@@ -45,6 +46,7 @@ module Reek
|
|
45
46
|
#
|
46
47
|
# A set of context-specific overrides for smell detectors.
|
47
48
|
#
|
49
|
+
# @api private
|
48
50
|
class Overrides
|
49
51
|
def initialize(hash)
|
50
52
|
@hash = hash
|
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'set'
|
2
|
-
require_relative '
|
2
|
+
require_relative 'smell_configuration'
|
3
3
|
|
4
4
|
module Reek
|
5
5
|
module Smells
|
@@ -7,10 +7,12 @@ module Reek
|
|
7
7
|
# Shared responsibilities of all smell detectors.
|
8
8
|
#
|
9
9
|
# See
|
10
|
-
# - docs/Basic-Smell-Options
|
11
|
-
# - docs/Code-Smells
|
12
|
-
# - docs/Configuration-Files
|
10
|
+
# - {file:docs/Basic-Smell-Options.md}
|
11
|
+
# - {file:docs/Code-Smells.md}
|
12
|
+
# - {file:docs/Configuration-Files.md}
|
13
13
|
# for details.
|
14
|
+
#
|
15
|
+
# @api private
|
14
16
|
class SmellDetector
|
15
17
|
attr_reader :source
|
16
18
|
|
@@ -30,7 +32,7 @@ module Reek
|
|
30
32
|
|
31
33
|
def default_config
|
32
34
|
{
|
33
|
-
|
35
|
+
SmellConfiguration::ENABLED_KEY => true,
|
34
36
|
EXCLUDE_KEY => DEFAULT_EXCLUDE_SET.dup
|
35
37
|
}
|
36
38
|
end
|
@@ -71,7 +73,7 @@ module Reek
|
|
71
73
|
|
72
74
|
def initialize(source, config = self.class.default_config)
|
73
75
|
@source = source
|
74
|
-
@config =
|
76
|
+
@config = SmellConfiguration.new(config)
|
75
77
|
@smells_found = []
|
76
78
|
end
|
77
79
|
|
@@ -98,7 +100,7 @@ module Reek
|
|
98
100
|
end
|
99
101
|
|
100
102
|
def enabled_for?(context)
|
101
|
-
enabled? && config_for(context)[
|
103
|
+
enabled? && config_for(context)[SmellConfiguration::ENABLED_KEY] != false
|
102
104
|
end
|
103
105
|
|
104
106
|
def exception?(context)
|
@@ -1,12 +1,13 @@
|
|
1
1
|
require_relative '../smells'
|
2
|
-
require_relative '
|
2
|
+
require_relative 'smell_detector'
|
3
3
|
require_relative '../configuration/app_configuration'
|
4
4
|
|
5
5
|
module Reek
|
6
|
-
module
|
6
|
+
module Smells
|
7
7
|
#
|
8
8
|
# Contains all the existing smells and exposes operations on them.
|
9
9
|
#
|
10
|
+
# @api private
|
10
11
|
class SmellRepository
|
11
12
|
attr_reader :detectors
|
12
13
|
|
@@ -19,10 +19,6 @@ module Reek
|
|
19
19
|
self.parameters = options.fetch(:parameters, {})
|
20
20
|
end
|
21
21
|
|
22
|
-
def smell_classes
|
23
|
-
[smell_detector.smell_category, smell_detector.smell_type]
|
24
|
-
end
|
25
|
-
|
26
22
|
def hash
|
27
23
|
sort_key.hash
|
28
24
|
end
|
@@ -35,10 +31,12 @@ module Reek
|
|
35
31
|
(self <=> other) == 0
|
36
32
|
end
|
37
33
|
|
34
|
+
# @api private
|
38
35
|
def matches?(klass, other_parameters = {})
|
39
36
|
smell_classes.include?(klass.to_s) && common_parameters_equal?(other_parameters)
|
40
37
|
end
|
41
38
|
|
39
|
+
# @api private
|
42
40
|
def report_on(listener)
|
43
41
|
listener.found_smell(self)
|
44
42
|
end
|
@@ -58,6 +56,10 @@ module Reek
|
|
58
56
|
|
59
57
|
private
|
60
58
|
|
59
|
+
def smell_classes
|
60
|
+
[smell_detector.smell_category, smell_detector.smell_type]
|
61
|
+
end
|
62
|
+
|
61
63
|
def common_parameters_equal?(other_parameters)
|
62
64
|
other_parameters.keys.each do |key|
|
63
65
|
unless parameters.key?(key)
|
@@ -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
|
@@ -9,7 +10,8 @@ module Reek
|
|
9
10
|
# +TooManyInstanceVariables' reports classes having more than a
|
10
11
|
# configurable number of instance variables.
|
11
12
|
#
|
12
|
-
# See docs/Too-Many-Instance-Variables for details.
|
13
|
+
# See {file:docs/Too-Many-Instance-Variables.md} for details.
|
14
|
+
# @api private
|
13
15
|
class TooManyInstanceVariables < SmellDetector
|
14
16
|
# The name of the config field that sets the maximum number of instance
|
15
17
|
# variables permitted in a class.
|
@@ -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
|
@@ -11,7 +12,8 @@ module Reek
|
|
11
12
|
# methods, and excludes methods inherited from superclasses or included
|
12
13
|
# modules.
|
13
14
|
#
|
14
|
-
# See docs/Too-Many-Methods for details.
|
15
|
+
# See {file:docs/Too-Many-Methods.md} for details.
|
16
|
+
# @api private
|
15
17
|
class TooManyMethods < SmellDetector
|
16
18
|
# The name of the config field that sets the maximum number of methods
|
17
19
|
# permitted in a class.
|
@@ -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
|
@@ -7,7 +8,8 @@ module Reek
|
|
7
8
|
#
|
8
9
|
# +TooManyStatements+ reports any method with more than 5 statements.
|
9
10
|
#
|
10
|
-
# See docs/Too-Many-Statements for details.
|
11
|
+
# See {file:docs/Too-Many-Statements.md} for details.
|
12
|
+
# @api private
|
11
13
|
class TooManyStatements < SmellDetector
|
12
14
|
# The name of the config field that sets the maximum number of
|
13
15
|
# statements permitted in any 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
|
@@ -15,7 +16,8 @@ module Reek
|
|
15
16
|
# * 1-character names
|
16
17
|
# * names ending with a number
|
17
18
|
#
|
18
|
-
# See docs/Uncommunicative-Method-Name for details.
|
19
|
+
# See {file:docs/Uncommunicative-Method-Name.md} for details.
|
20
|
+
# @api private
|
19
21
|
class UncommunicativeMethodName < SmellDetector
|
20
22
|
# The name of the config field that lists the regexps of
|
21
23
|
# smelly names to be reported.
|
@@ -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
|
# * 1-character names
|
16
17
|
# * names ending with a number
|
17
18
|
#
|
18
|
-
# See docs/Uncommunicative-Module-Name for details.
|
19
|
+
# See {file:docs/Uncommunicative-Module-Name.md} for details.
|
20
|
+
# @api private
|
19
21
|
class UncommunicativeModuleName < SmellDetector
|
20
22
|
# The name of the config field that lists the regexps of
|
21
23
|
# smelly names to be reported.
|
@@ -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
|
# * 1-character names
|
16
17
|
# * names ending with a number
|
17
18
|
#
|
18
|
-
# See docs/Uncommunicative-Parameter-Name for details.
|
19
|
+
# See {file:docs/Uncommunicative-Parameter-Name.md} for details.
|
20
|
+
# @api private
|
19
21
|
class UncommunicativeParameterName < SmellDetector
|
20
22
|
# The name of the config field that lists the regexps of
|
21
23
|
# smelly names to be reported.
|
@@ -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
|
# * 1-character names
|
16
17
|
# * names ending with a number
|
17
18
|
#
|
18
|
-
# See docs/Uncommunicative-Variable-Name for details.
|
19
|
+
# See {file:docs/Uncommunicative-Variable-Name.md} for details.
|
20
|
+
# @api private
|
19
21
|
class UncommunicativeVariableName < SmellDetector
|
20
22
|
# The name of the config field that lists the regexps of
|
21
23
|
# smelly names to be reported.
|
@@ -1,11 +1,13 @@
|
|
1
1
|
require_relative 'smell_detector'
|
2
|
+
require_relative 'smell_warning'
|
2
3
|
|
3
4
|
module Reek
|
4
5
|
module Smells
|
5
6
|
#
|
6
7
|
# Methods should use their parameters.
|
7
8
|
#
|
8
|
-
# See docs/Unused-Parameters for details.
|
9
|
+
# See {file:docs/Unused-Parameters.md} for details.
|
10
|
+
# @api private
|
9
11
|
class UnusedParameters < SmellDetector
|
10
12
|
def self.smell_category
|
11
13
|
'UnusedCode'
|
@@ -1,5 +1,6 @@
|
|
1
|
+
require_relative '../ast/reference_collector'
|
1
2
|
require_relative 'smell_detector'
|
2
|
-
require_relative '
|
3
|
+
require_relative 'smell_warning'
|
3
4
|
|
4
5
|
module Reek
|
5
6
|
module Smells
|
@@ -34,7 +35,8 @@ module Reek
|
|
34
35
|
# If the method does refer to self, but refers to some other object more,
|
35
36
|
# +FeatureEnvy+ is reported instead.
|
36
37
|
#
|
37
|
-
# See docs/Utility-Function for details.
|
38
|
+
# See {file:docs/Utility-Function.md} for details.
|
39
|
+
# @api private
|
38
40
|
class UtilityFunction < SmellDetector
|
39
41
|
def self.smell_category
|
40
42
|
'LowCohesion'
|
@@ -52,6 +54,7 @@ module Reek
|
|
52
54
|
# @return [Array<SmellWarning>]
|
53
55
|
#
|
54
56
|
def examine_context(method_ctx)
|
57
|
+
return [] if method_ctx.exp.singleton_method?
|
55
58
|
return [] if method_ctx.num_statements == 0
|
56
59
|
return [] if method_ctx.references_self?
|
57
60
|
return [] if num_helper_methods(method_ctx).zero?
|
@@ -1,15 +1,17 @@
|
|
1
1
|
require_relative '../cli/silencer'
|
2
2
|
Reek::CLI::Silencer.silently do
|
3
|
-
require 'parser/
|
3
|
+
require 'parser/ruby22'
|
4
4
|
end
|
5
|
-
require_relative '../
|
6
|
-
require_relative '../
|
5
|
+
require_relative '../tree_dresser'
|
6
|
+
require_relative '../ast/node'
|
7
7
|
|
8
8
|
module Reek
|
9
|
+
# @api private
|
9
10
|
module Source
|
10
11
|
#
|
11
12
|
# A +Source+ object represents a chunk of Ruby source code.
|
12
13
|
#
|
14
|
+
# @api private
|
13
15
|
class SourceCode
|
14
16
|
attr_reader :description
|
15
17
|
|
@@ -18,7 +20,7 @@ module Reek
|
|
18
20
|
# code - ruby code as String
|
19
21
|
# description - in case of STDIN this is "STDIN" otherwise it's a filepath as String
|
20
22
|
# parser - the parser to use for generating AST's out of the given source
|
21
|
-
def initialize(code, description, parser = Parser::
|
23
|
+
def initialize(code, description, parser = Parser::Ruby22)
|
22
24
|
@source = code
|
23
25
|
@description = description
|
24
26
|
@parser = parser
|
@@ -30,9 +32,9 @@ module Reek
|
|
30
32
|
# - from IO (STDIN) a la `echo "class Foo; end" | reek`
|
31
33
|
# - from String via our rspec matchers a la `expect("class Foo; end").to reek`
|
32
34
|
#
|
33
|
-
# source
|
35
|
+
# @param source [File|IO|String] - the given source
|
34
36
|
#
|
35
|
-
#
|
37
|
+
# @return an instance of SourceCode
|
36
38
|
def self.from(source)
|
37
39
|
case source
|
38
40
|
when File then new(source.read, source.path)
|
@@ -41,9 +43,37 @@ module Reek
|
|
41
43
|
end
|
42
44
|
end
|
43
45
|
|
44
|
-
# Parses the given source into an AST.
|
46
|
+
# Parses the given source into an AST and associates the source code comments with it.
|
47
|
+
# This AST is then traversed by a TreeDresser which adorns the nodes in the AST
|
48
|
+
# with our SexpExtensions.
|
49
|
+
# Finally this AST is returned where each node is an anonymous subclass of Reek::AST::Node
|
45
50
|
#
|
46
|
-
#
|
51
|
+
# Important to note is that reek will not fail on unparseable files but rather print out
|
52
|
+
# a warning and then just continue.
|
53
|
+
#
|
54
|
+
# Given this @source:
|
55
|
+
#
|
56
|
+
# # comment about C
|
57
|
+
# class C
|
58
|
+
# def m
|
59
|
+
# puts 'nada'
|
60
|
+
# end
|
61
|
+
# end
|
62
|
+
#
|
63
|
+
# this method would return something that looks like
|
64
|
+
#
|
65
|
+
# (class
|
66
|
+
# (const nil :C) nil
|
67
|
+
# (def :m
|
68
|
+
# (args)
|
69
|
+
# (send nil :puts
|
70
|
+
# (str "nada"))))
|
71
|
+
#
|
72
|
+
# where each node is possibly adorned with our SexpExtensions (see ast/ast_node_class_map
|
73
|
+
# and ast/sexp_extensions for details).
|
74
|
+
#
|
75
|
+
# @return [Anonymous subclass of Reek::AST::Node] the AST presentation
|
76
|
+
# for the given source
|
47
77
|
def syntax_tree
|
48
78
|
@syntax_tree ||=
|
49
79
|
begin
|
@@ -53,8 +83,9 @@ module Reek
|
|
53
83
|
$stderr.puts "#{description}: #{error.class.name}: #{error}"
|
54
84
|
end
|
55
85
|
|
86
|
+
# See https://whitequark.github.io/parser/Parser/Source/Comment/Associator.html
|
56
87
|
comment_map = Parser::Source::Comment.associate(ast, comments) if ast
|
57
|
-
|
88
|
+
TreeDresser.new.dress(ast, comment_map)
|
58
89
|
end
|
59
90
|
end
|
60
91
|
end
|