Skip to content

Commit

Permalink
Replace CommentConfig#directive_parts with DirectiveComment instance
Browse files Browse the repository at this point in the history
  • Loading branch information
Andrei Eres authored and bbatsov committed Mar 17, 2021
1 parent 80ea6a5 commit 6746f15
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 24 deletions.
28 changes: 4 additions & 24 deletions lib/rubocop/comment_config.rb
Expand Up @@ -4,9 +4,6 @@ module RuboCop
# This class parses the special `rubocop:disable` comments in a source
# and provides a way to check if each cop is enabled at arbitrary line.
class CommentConfig
# @api private
REDUNDANT_DISABLE = 'Lint/RedundantCopDisableDirective'

CopAnalysis = Struct.new(:line_ranges, :start_line_number)

attr_reader :processed_source
Expand Down Expand Up @@ -130,35 +127,18 @@ def directive_on_comment_line?(comment)

def each_directive
processed_source.comments.each do |comment|
directive = directive_parts(comment)
next unless directive
directive = DirectiveComment.new(comment)
next unless directive.cop_names

yield comment, *directive
# TODO: pass only directive
yield directive.comment, directive.cop_names, directive.disabled?
end
end

def directive_parts(comment)
match_captures = DirectiveComment.new(comment).match_captures
return unless match_captures

switch, cops_string = match_captures

cop_names =
cops_string == 'all' ? all_cop_names : cops_string.split(/,\s*/)

disabled = %w[disable todo].include?(switch)

[cop_names, disabled]
end

def qualified_cop_name(cop_name)
Cop::Registry.qualified_cop_name(cop_name.strip, processed_source.file_path)
end

def all_cop_names
@all_cop_names ||= Cop::Registry.global.names - [REDUNDANT_DISABLE]
end

def non_comment_token_line_numbers
@non_comment_token_line_numbers ||= begin
non_comment_tokens = processed_source.tokens.reject(&:comment?)
Expand Down
21 changes: 21 additions & 0 deletions lib/rubocop/directive_comment.rb
Expand Up @@ -5,6 +5,8 @@ module RuboCop
# special `rubocop:disable` and `rubocop:enable` comment and exposes what
# cops it contains.
class DirectiveComment
# @api private
REDUNDANT_COP = 'Lint/RedundantCopDisableDirective'
# @api private
COP_NAME_PATTERN = '([A-Z]\w+/)*(?:[A-Z]\w+)'
# @api private
Expand Down Expand Up @@ -47,10 +49,29 @@ def match_captures
@match_captures ||= comment.text.match(DIRECTIVE_COMMENT_REGEXP)&.captures
end

# Checks if this directive disables cops
def disabled?
%w[disable todo].include?(mode)
end

# Checks if all cops specified in this directive
def all_cops?
cops == 'all'
end

# Returns array of specified in this directive cop names
def cop_names
@cop_names ||= all_cops? ? all_cop_names : parsed_cop_names
end

private

def parsed_cop_names
(cops || '').split(/,\s*/)
end

def all_cop_names
Cop::Registry.global.names - [REDUNDANT_COP]
end
end
end
55 changes: 55 additions & 0 deletions spec/rubocop/directive_comment_spec.rb
Expand Up @@ -116,4 +116,59 @@
end
end
end

describe '#disabled?' do
subject { directive_comment.disabled? }

[
['when disable', '# rubocop:disable all', true],
['when enable', '# rubocop:enable Foo/Bar', false],
['when todo', '# rubocop:todo all', true]
].each do |example|
context example[0] do
let(:text) { example[1] }

it { is_expected.to eq example[2] }
end
end
end

describe '#all_cops?' do
subject { directive_comment.all_cops? }

[
['when mentioned all', '# rubocop:disable all', true],
['when mentioned specific cops', '# rubocop:enable Foo/Bar', false]
].each do |example|
context example[0] do
let(:text) { example[1] }

it { is_expected.to eq example[2] }
end
end
end

describe '#cop_names' do
subject(:cop_names) { directive_comment.cop_names }

context 'when all cops mentioned' do
let(:comment_cop_names) { 'all' }
let(:global) { instance_double(RuboCop::Cop::Registry, names: names) }
let(:names) { %w[all_names Lint/RedundantCopDisableDirective] }

before { allow(RuboCop::Cop::Registry).to receive(:global).and_return(global) }

it 'returns all cop names except redundant' do
expect(cop_names).to eq(%w[all_names])
end
end

context 'when cop specified' do
let(:comment_cop_names) { 'Foo/Bar' }

it 'returns parsed cop names' do
expect(cop_names).to eq(%w[Foo/Bar])
end
end
end
end

0 comments on commit 6746f15

Please sign in to comment.