Skip to content

Commit

Permalink
Reduce ABC complexity
Browse files Browse the repository at this point in the history
  • Loading branch information
buehmann authored and bbatsov committed Oct 23, 2019
1 parent 60be68f commit 611ed0d
Show file tree
Hide file tree
Showing 15 changed files with 119 additions and 68 deletions.
11 changes: 7 additions & 4 deletions lib/rubocop/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -83,18 +83,21 @@ def execute_runners(paths)

def maybe_run_line_length_cop(paths)
if !line_length_enabled?(@config_store.for(Dir.pwd))
puts Rainbow("#{PHASE_1} #{PHASE_1_DISABLED}").yellow
''
skip_line_length_cop(PHASE_1_DISABLED)
elsif !same_max_line_length?(
@config_store.for(Dir.pwd), ConfigLoader.default_configuration
)
puts Rainbow("#{PHASE_1} #{PHASE_1_OVERRIDDEN}").yellow
''
skip_line_length_cop(PHASE_1_OVERRIDDEN)
else
run_line_length_cop_auto_gen_config(paths)
end
end

def skip_line_length_cop(reason)
puts Rainbow("#{PHASE_1} #{reason}").yellow
''
end

def line_length_enabled?(config)
line_length_cop(config)['Enabled']
end
Expand Down
7 changes: 7 additions & 0 deletions lib/rubocop/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,13 @@ def signature
@signature ||= Digest::SHA1.hexdigest(to_s)
end

# True if this is a config file that is shipped with RuboCop
def internal?
base_config_path = File.expand_path(File.join(ConfigLoader::RUBOCOP_HOME,
'config'))
File.expand_path(loaded_path).start_with?(base_config_path)
end

def make_excludes_absolute
each_key do |key|
@validator.validate_section_presence(key)
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/config_loader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def load_file(file)

add_missing_namespaces(path, hash)

resolver.resolve_inheritance_from_gems(hash, hash.delete('inherit_gem'))
resolver.resolve_inheritance_from_gems(hash)
resolver.resolve_inheritance(path, hash, file, debug?)

hash.delete('inherit_from')
Expand Down
3 changes: 2 additions & 1 deletion lib/rubocop/config_loader_resolver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ def resolve_inheritance(path, hash, file, debug)
end
end

def resolve_inheritance_from_gems(hash, gems)
def resolve_inheritance_from_gems(hash)
gems = hash.delete('inherit_gem')
(gems || {}).each_pair do |gem_name, config_path|
if gem_name == 'rubocop'
raise ArgumentError,
Expand Down
17 changes: 8 additions & 9 deletions lib/rubocop/config_validator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,7 @@ def initialize(config)

def validate
# Don't validate RuboCop's own files. Avoids infinite recursion.
base_config_path = File.expand_path(File.join(ConfigLoader::RUBOCOP_HOME,
'config'))
return if File.expand_path(@config.loaded_path)
.start_with?(base_config_path)
return if @config.internal?

valid_cop_names, invalid_cop_names = @config.keys.partition do |key|
ConfigLoader.default_configuration.key?(key)
Expand Down Expand Up @@ -133,12 +130,14 @@ def validate_parameter_names(valid_cop_names)
@config[name].each_key do |param|
next if COMMON_PARAMS.include?(param) || default_config.key?(param)

message =
"Warning: #{name} does not support #{param} parameter.\n\n" \
"Supported parameters are:\n\n" \
" - #{(default_config.keys - INTERNAL_PARAMS).join("\n - ")}\n"
supported_params = default_config.keys - INTERNAL_PARAMS
warn Rainbow(<<~MESSAGE).yellow
Warning: #{name} does not support #{param} parameter.
warn Rainbow(message).yellow.to_s
Supported parameters are:
- #{supported_params.join("\n - ")}
MESSAGE
end
end
end
Expand Down
22 changes: 15 additions & 7 deletions lib/rubocop/cop/commissioner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,17 +64,25 @@ def reset_errors
end

def remove_irrelevant_cops(filename)
@cops.reject! { |cop| cop.excluded_file?(filename) }
@cops.reject! do |cop|
cop.class.respond_to?(:support_target_ruby_version?) &&
!cop.class.support_target_ruby_version?(cop.target_ruby_version)
end
@cops.reject! do |cop|
cop.class.respond_to?(:support_target_rails_version?) &&
!cop.class.support_target_rails_version?(cop.target_rails_version)
cop.excluded_file?(filename) ||
!support_target_ruby_version?(cop) ||
!support_target_rails_version?(cop)
end
end

def support_target_ruby_version?(cop)
return true unless cop.class.respond_to?(:support_target_ruby_version?)

cop.class.support_target_ruby_version?(cop.target_ruby_version)
end

def support_target_rails_version?(cop)
return true unless cop.class.respond_to?(:support_target_rails_version?)

cop.class.support_target_rails_version?(cop.target_rails_version)
end

def reset_callbacks
@callbacks.clear
end
Expand Down
11 changes: 8 additions & 3 deletions lib/rubocop/cop/layout/end_of_line.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,7 @@ class EndOfLine < Cop
MSG_MISSING = 'Carriage return character missing.'

def investigate(processed_source)
last_token = processed_source.tokens.last
last_line =
last_token ? last_token.line : processed_source.lines.length
last_line = last_line(processed_source)

processed_source.raw_source.each_line.with_index do |line, index|
break if index >= last_line
Expand Down Expand Up @@ -81,6 +79,13 @@ def offense_message(line)
else MSG_MISSING if line !~ /\r$/
end
end

private

def last_line(processed_source)
last_token = processed_source.tokens.last
last_token ? last_token.line : processed_source.lines.length
end
end
end
end
Expand Down
16 changes: 9 additions & 7 deletions lib/rubocop/cop/layout/indent_first_argument.rb
Original file line number Diff line number Diff line change
Expand Up @@ -228,19 +228,21 @@ def column_of(range)
# containing the previous line that's not a comment line or a blank
# line.
def previous_code_line(line_number)
@comment_lines ||=
processed_source
.comments
.select { |c| begins_its_line?(c.loc.expression) }
.map { |c| c.loc.line }

line = ''
while line.blank? || @comment_lines.include?(line_number)
while line.blank? || comment_lines.include?(line_number)
line_number -= 1
line = processed_source.lines[line_number - 1]
end
line
end

def comment_lines
@comment_lines ||=
processed_source
.comments
.select { |c| begins_its_line?(c.loc.expression) }
.map { |c| c.loc.line }
end
end
end
end
Expand Down
17 changes: 12 additions & 5 deletions lib/rubocop/cop/naming/file_name.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,21 +50,28 @@ def investigate(processed_source)
def for_bad_filename(file_path)
basename = File.basename(file_path)
msg = if filename_good?(basename)
return unless expect_matching_definition?
return if find_class_or_module(processed_source.ast,
to_namespace(file_path))
return if matching_definition?(file_path)

no_definition_message(basename, file_path)
else
return if ignore_executable_scripts? &&
processed_source.start_with?('#!')
return if bad_filename_allowed?

other_message(basename)
end

yield source_range(processed_source.buffer, 1, 0), msg
end

def matching_definition?(file_path)
return true unless expect_matching_definition?

find_class_or_module(processed_source.ast, to_namespace(file_path))
end

def bad_filename_allowed?
ignore_executable_scripts? && processed_source.start_with?('#!')
end

def no_definition_message(basename, file_path)
format(MSG_NO_DEFINITION,
basename: basename,
Expand Down
18 changes: 11 additions & 7 deletions lib/rubocop/cop/style/copyright.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,7 @@ def investigate(processed_source)
end

def autocorrect(token)
raise Warning, AUTOCORRECT_EMPTY_WARNING if autocorrect_notice.empty?

regex = Regexp.new(notice)
unless autocorrect_notice =~ regex
raise Warning, "AutocorrectNotice '#{autocorrect_notice}' must " \
"match Notice /#{notice}/"
end
verify_autocorrect_notice!

lambda do |corrector|
range = token.nil? ? range_between(0, 0) : token.pos
Expand All @@ -57,6 +51,16 @@ def autocorrect_notice
cop_config['AutocorrectNotice']
end

def verify_autocorrect_notice!
raise Warning, AUTOCORRECT_EMPTY_WARNING if autocorrect_notice.empty?

regex = Regexp.new(notice)
return if autocorrect_notice =~ regex

raise Warning, "AutocorrectNotice '#{autocorrect_notice}' must " \
"match Notice /#{notice}/"
end

def insert_notice_before(processed_source)
token_index = 0
token_index += 1 if shebang_token?(processed_source, token_index)
Expand Down
9 changes: 5 additions & 4 deletions lib/rubocop/cop/style/format_string.rb
Original file line number Diff line number Diff line change
Expand Up @@ -106,14 +106,15 @@ def autocorrect_from_percent(corrector, node)
end

def autocorrect_to_percent(corrector, node)
format = node.first_argument.source
format_arg, *param_args = node.arguments
format = format_arg.source

args = if node.arguments.size == 2
arg = node.arguments.last
args = if param_args.one?
arg = param_args.last

arg.hash_type? ? "{ #{arg.source} }" : arg.source
else
"[#{node.arguments[1..-1].map(&:source).join(', ')}]"
"[#{param_args.map(&:source).join(', ')}]"
end

corrector.replace(node.loc.expression, "#{format} % #{args}")
Expand Down
7 changes: 4 additions & 3 deletions lib/rubocop/cop/style/inverse_methods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -122,18 +122,19 @@ def correct_inverse_block(node)
end

def correct_inverse_selector(block, corrector)
selector = block.loc.selector.source
selector_loc = block.loc.selector
selector = selector_loc.source

if NEGATED_EQUALITY_METHODS.include?(selector.to_sym)
selector[0] = '='
corrector.replace(block.loc.selector, selector)
corrector.replace(selector_loc, selector)
else
if block.loc.dot
range = dot_range(block.loc)
corrector.remove(range)
end

corrector.remove(block.loc.selector)
corrector.remove(selector_loc)
end
end

Expand Down
6 changes: 6 additions & 0 deletions lib/rubocop/options.rb
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,12 @@ def initialize(options)
@options = options
end

def validate_cop_options
%i[only except].each do |opt|
OptionsValidator.validate_cop_list(@options[opt])
end
end

# rubocop:disable Metrics/AbcSize
def validate_compatibility # rubocop:disable Metrics/MethodLength
if only_includes_unneeded_disable?
Expand Down
23 changes: 12 additions & 11 deletions lib/rubocop/runner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -104,18 +104,13 @@ def list_files(paths)
end

def process_file(file)
puts "Scanning #{file}" if @options[:debug]
file_started(file)

offenses = file_offenses(file)
if @options[:display_only_fail_level_offenses]
offenses = offenses.select { |o| considered_failure?(o) }
end
formatter_set.file_finished(file, offenses)
offenses
rescue InfiniteCorrectionLoop => e
formatter_set.file_finished(file, e.offenses.compact.sort.freeze)
offenses = e.offenses.compact.sort.freeze
raise
ensure
file_finished(file, offenses || [])
end

def file_offenses(file)
Expand Down Expand Up @@ -189,11 +184,19 @@ def autocorrect_unneeded_disables(file, source, cop, offenses)
end

def file_started(file)
puts "Scanning #{file}" if @options[:debug]
formatter_set.file_started(file,
cli_options: @options,
config_store: @config_store)
end

def file_finished(file, offenses)
if @options[:display_only_fail_level_offenses]
offenses = offenses.select { |o| considered_failure?(o) }
end
formatter_set.file_finished(file, offenses)
end

def cached_run?
@cached_run ||=
(@options[:cache] == 'true' ||
Expand Down Expand Up @@ -291,9 +294,7 @@ def mobilized_cop_classes(config)
@mobilized_cop_classes[config.object_id] ||= begin
cop_classes = Cop::Cop.all

%i[only except].each do |opt|
OptionsValidator.validate_cop_list(@options[opt])
end
OptionsValidator.new(@options).validate_cop_options

if @options[:only]
cop_classes.select! { |c| c.match?(@options[:only]) }
Expand Down
18 changes: 12 additions & 6 deletions lib/rubocop/target_finder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,7 @@ def target_files_in_dir(base_dir = Dir.pwd)
to_inspect?(file, hidden_files, base_dir_config)
end

if fail_fast?
# Most recently modified file first.
target_files.sort_by! { |path| -Integer(File.mtime(path)) }
else
target_files.sort!
end
target_files.sort_by!(&order)
end

def to_inspect?(file, hidden_files, base_dir_config)
Expand Down Expand Up @@ -186,5 +181,16 @@ def process_explicit_path(path)
config.file_to_exclude?(file)
end
end

private

def order
if fail_fast?
# Most recently modified file first.
->(path) { -Integer(File.mtime(path)) }
else
:itself
end
end
end
end

0 comments on commit 611ed0d

Please sign in to comment.