lib/reek/smells/smell_detector.rb in reek-1.1.3 vs lib/reek/smells/smell_detector.rb in reek-1.2.0

- old
+ new

@@ -1,5 +1,7 @@ +require 'reek/configuration' + class Class def name_words class_name = name.split(/::/)[-1] class_name.gsub(/([a-z])([A-Z])/) { |sub| "#{$1} #{$2}"}.split end @@ -13,54 +15,119 @@ # The name of the config field that lists the names of code contexts # that should not be checked. Add this field to the config for each # smell that should ignore this code element. EXCLUDE_KEY = 'exclude' - # The name fo the config field that specifies whether a smell is - # enabled. Set to +true+ or +false+. - ENABLED_KEY = 'enabled' - - def self.class_name - self.name.split(/::/)[-1] + # The default value for the +EXCLUDE_KEY+ if it isn't specified + # in any configuration file. + DEFAULT_EXCLUDE_SET = [] + + class << self + def class_name + self.name.split(/::/)[-1] + end + + def contexts # :nodoc: + [:defn, :defs] + end + + def default_config + { + SmellConfiguration::ENABLED_KEY => true, + EXCLUDE_KEY => DEFAULT_EXCLUDE_SET + } + end + + def create(config) + new(config[class_name]) + end + + def listen(hooks, config) + detector = create(config) + detector.listen_to(hooks) + detector + end end - def self.contexts # :nodoc: - [:defn, :defs] + def initialize(config = self.class.default_config) + @config = SmellConfiguration.new(config) + @smells_found = Set.new + @masked = false end - - def self.default_config - { - ENABLED_KEY => true, - EXCLUDE_KEY => [] - } + + def listen_to(hooks) + self.class.contexts.each { |ctx| hooks[ctx] << self } end - def self.listen(hooks, config) - detector = new(config[class_name]) - contexts.each { |ctx| hooks[ctx] << detector } + # SMELL: Getter (only used in 1 test) + def enabled? + @config.enabled? end - def initialize(config) - @enabled = config[ENABLED_KEY] - @exceptions = config[EXCLUDE_KEY] + def configure(config) + my_part = config[self.class.name.split(/::/)[-1]] + return unless my_part + configure_with(my_part) end - def examine(context, report) - before = report.size - examine_context(context, report) if @enabled and !exception?(context) - report.length > before + def configure_with(config) + @config.hash.adopt!(config) end - def examine_context(context, report) + def copy + self.class.new(@config.hash.deep_copy) end + + def supersede_with(config) + clone = self.copy + @masked = true + clone.configure_with(config) + clone + end + + def examine(context) + before = @smells_found.size + examine_context(context) if @config.enabled? and !exception?(context) + @smells_found.length > before + end + + def examine_context(context) + end def exception?(context) - return false if @exceptions.nil? or @exceptions.length == 0 - context.matches?(@exceptions) + context.matches?(value(EXCLUDE_KEY, context, DEFAULT_EXCLUDE_SET)) end + def found(scope, warning) + smell = SmellWarning.new(self, scope, warning, @masked) + @smells_found << smell + smell + end + + def has_smell?(patterns) + return false if @masked + @smells_found.each { |warning| return true if warning.contains_all?(patterns) } + false + end + + def report_on(report) + @smells_found.each { |smell| smell.report_on(report) } + end + + def num_smells + @masked ? 0 : @smells_found.length + end + + def smelly? + (not @masked) and (@smells_found.length > 0) + end + def smell_name self.class.name_words.join(' ') + end + + def value(key, ctx, fall_back) + @config.value(key, ctx, fall_back) end end end end