Class: RuboCop::DirectiveComment
- Inherits:
-
Object
- Object
- RuboCop::DirectiveComment
- Defined in:
- lib/rubocop/directive_comment.rb
Overview
This class wraps the Parser::Source::Comment object that represents a
special rubocop:disable and rubocop:enable comment and exposes what
cops it contains.
Constant Summary collapse
- LINT_DEPARTMENT =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
'Lint'- LINT_REDUNDANT_DIRECTIVE_COP =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
"#{LINT_DEPARTMENT}/RedundantCopDisableDirective"- LINT_SYNTAX_COP =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
"#{LINT_DEPARTMENT}/Syntax"- STYLE_DISABLE_COPS_DIRECTIVE_COP =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
'Style/DisableCopsWithinSourceCodeDirective'- COP_NAME_PATTERN =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
'([A-Za-z]\w+/)*(?:[A-Za-z]\w+)'- COP_NAME_PATTERN_NC =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
'(?:[A-Za-z]\w+/)*[A-Za-z]\w+'- COP_NAMES_PATTERN_NC =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
"(?:#{COP_NAME_PATTERN_NC} , )*#{COP_NAME_PATTERN_NC}"- COP_NAMES_PATTERN =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
"(?:#{COP_NAME_PATTERN} , )*#{COP_NAME_PATTERN}"- COPS_PATTERN =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
"(all|#{COP_NAMES_PATTERN})"- PUSH_POP_ARGS_PATTERN =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
"([+\\-]#{COP_NAME_PATTERN_NC}(?:\\s+[+\\-]#{COP_NAME_PATTERN_NC})*)"- AVAILABLE_MODES =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
%w[disable enable todo push pop disable-next todo-next].freeze
- MODES_PATTERN =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
Longest first, so a
-nextmode is not matched as its prefix (-is a word boundary). AVAILABLE_MODES.sort_by { |mode| -mode.length }.join('|').freeze
- DIRECTIVE_MARKER_PATTERN =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
'# rubocop : '- DIRECTIVE_MARKER_REGEXP =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
Regexp.new(DIRECTIVE_MARKER_PATTERN.gsub(' ', '\s*'))
- DIRECTIVE_HEADER_PATTERN =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
"#{DIRECTIVE_MARKER_PATTERN}((?:#{MODES_PATTERN}))\\b"- DIRECTIVE_COMMENT_REGEXP =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
Regexp.new( "#{DIRECTIVE_HEADER_PATTERN}(?:\\s+#{COPS_PATTERN}|\\s+#{PUSH_POP_ARGS_PATTERN})?" .gsub(' ', '\s*') )
- TRAILING_COMMENT_MARKER =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
'--'- MALFORMED_DIRECTIVE_WITHOUT_COP_NAME_REGEXP =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
Regexp.new( "\\A#{DIRECTIVE_HEADER_PATTERN}\\s*\\z".gsub(' ', '\s*') )
Instance Attribute Summary collapse
-
#comment ⇒ Object
readonly
Returns the value of attribute comment.
-
#cop_registry ⇒ Object
readonly
Returns the value of attribute cop_registry.
-
#cops ⇒ Object
readonly
Returns the value of attribute cops.
-
#mode ⇒ Object
readonly
Returns the value of attribute mode.
Class Method Summary collapse
Instance Method Summary collapse
-
#all_cops? ⇒ Boolean
Checks if all cops specified in this directive.
-
#cop_names ⇒ Object
Returns array of specified in this directive cop names.
-
#department_names ⇒ Object
Returns array of specified in this directive department names when all department disabled.
- #directive_count ⇒ Object
-
#disable_next? ⇒ Boolean
Checks if this directive disables cops for the next statement only.
-
#disabled? ⇒ Boolean
Checks if this directive disables cops.
-
#disabled_all? ⇒ Boolean
Checks if this directive disables all cops.
-
#enabled? ⇒ Boolean
Checks if this directive enables cops.
-
#enabled_all? ⇒ Boolean
Checks if this directive enables all cops.
-
#in_directive_department?(cop) ⇒ Boolean
Checks if directive departments include cop.
-
#initialize(comment, cop_registry = Cop::Registry.global) ⇒ DirectiveComment
constructor
A new instance of DirectiveComment.
-
#line_number ⇒ Object
Returns line number for directive.
-
#malformed? ⇒ Boolean
Checks if the comment is malformed as a
# rubocop:directive. -
#match?(cop_names) ⇒ Boolean
Checks if this directive contains all the given cop names.
-
#match_captures ⇒ Object
Returns match captures to directive comment pattern.
-
#missing_cop_name? ⇒ Boolean
Checks if the directive comment is missing a cop name.
-
#overridden_by_department?(cop) ⇒ Boolean
Checks if cop department has already used in directive comment.
-
#pop? ⇒ Boolean
Checks if this directive is a pop.
-
#push? ⇒ Boolean
Checks if this directive is a push.
-
#push_args ⇒ Object
Returns the push arguments as a hash of cop names with their operations.
- #range ⇒ Object
-
#range_with_reason ⇒ Object
#rangestops at the cop list, so a--reason sits outside it. -
#raw_cop_names ⇒ Object
Returns an array of cops for this directive comment, without resolving departments.
-
#reason ⇒ Object
The text of the directive's optional
--trailing comment, ornilwhen there is none. -
#single_line? ⇒ Boolean
Checks if this directive relates to single line.
-
#start_with_marker? ⇒ Boolean
Checks if the comment starts with
# rubocop:marker.
Constructor Details
#initialize(comment, cop_registry = Cop::Registry.global) ⇒ DirectiveComment
Returns a new instance of DirectiveComment.
58 59 60 61 62 63 64 |
# File 'lib/rubocop/directive_comment.rb', line 58 def initialize(comment, cop_registry = Cop::Registry.global) @comment = comment @cop_registry = cop_registry match_data = comment.text.match(DIRECTIVE_COMMENT_REGEXP) @match_data = match_data&.pre_match&.match?(/\A#\s*\z/) ? nil : match_data @mode, @cops = match_captures end |
Instance Attribute Details
#comment ⇒ Object (readonly)
Returns the value of attribute comment.
56 57 58 |
# File 'lib/rubocop/directive_comment.rb', line 56 def comment @comment end |
#cop_registry ⇒ Object (readonly)
Returns the value of attribute cop_registry.
56 57 58 |
# File 'lib/rubocop/directive_comment.rb', line 56 def cop_registry @cop_registry end |
#cops ⇒ Object (readonly)
Returns the value of attribute cops.
56 57 58 |
# File 'lib/rubocop/directive_comment.rb', line 56 def cops @cops end |
#mode ⇒ Object (readonly)
Returns the value of attribute mode.
56 57 58 |
# File 'lib/rubocop/directive_comment.rb', line 56 def mode @mode end |
Class Method Details
.before_comment(line) ⇒ Object
52 53 54 |
# File 'lib/rubocop/directive_comment.rb', line 52 def self.before_comment(line) line.split(DIRECTIVE_COMMENT_REGEXP).first end |
Instance Method Details
#all_cops? ⇒ Boolean
Checks if all cops specified in this directive
182 183 184 |
# File 'lib/rubocop/directive_comment.rb', line 182 def all_cops? cops == 'all' end |
#cop_names ⇒ Object
Returns array of specified in this directive cop names
187 188 189 |
# File 'lib/rubocop/directive_comment.rb', line 187 def cop_names @cop_names ||= all_cops? ? all_cop_names : parsed_cop_names end |
#department_names ⇒ Object
Returns array of specified in this directive department names when all department disabled
198 199 200 |
# File 'lib/rubocop/directive_comment.rb', line 198 def department_names raw_cop_names.select { |cop| department?(cop) } end |
#directive_count ⇒ Object
212 213 214 |
# File 'lib/rubocop/directive_comment.rb', line 212 def directive_count raw_cop_names.count end |
#disable_next? ⇒ Boolean
Checks if this directive disables cops for the next statement only
147 148 149 |
# File 'lib/rubocop/directive_comment.rb', line 147 def disable_next? %w[disable-next todo-next].include?(mode) end |
#disabled? ⇒ Boolean
Checks if this directive disables cops
142 143 144 |
# File 'lib/rubocop/directive_comment.rb', line 142 def disabled? %w[disable todo].include?(mode) || disable_next? end |
#disabled_all? ⇒ Boolean
Checks if this directive disables all cops
177 178 179 |
# File 'lib/rubocop/directive_comment.rb', line 177 def disabled_all? disabled? && all_cops? end |
#enabled? ⇒ Boolean
Checks if this directive enables cops
152 153 154 |
# File 'lib/rubocop/directive_comment.rb', line 152 def enabled? mode == 'enable' end |
#enabled_all? ⇒ Boolean
Checks if this directive enables all cops
172 173 174 |
# File 'lib/rubocop/directive_comment.rb', line 172 def enabled_all? !disabled? && all_cops? end |
#in_directive_department?(cop) ⇒ Boolean
Checks if directive departments include cop
203 204 205 |
# File 'lib/rubocop/directive_comment.rb', line 203 def in_directive_department?(cop) department_names.any? { |department| cop.start_with?(department) } end |
#line_number ⇒ Object
Returns line number for directive
217 218 219 |
# File 'lib/rubocop/directive_comment.rb', line 217 def line_number comment.source_range.line end |
#malformed? ⇒ Boolean
Checks if the comment is malformed as a # rubocop: directive
72 73 74 75 76 77 78 |
# File 'lib/rubocop/directive_comment.rb', line 72 def malformed? return true if !start_with_marker? || @match_data.nil? return true if missing_cop_name? tail = @match_data.post_match.lstrip !(tail.empty? || tail.start_with?(TRAILING_COMMENT_MARKER)) end |
#match?(cop_names) ⇒ Boolean
Checks if this directive contains all the given cop names
105 106 107 |
# File 'lib/rubocop/directive_comment.rb', line 105 def match?(cop_names) parsed_cop_names.uniq.sort == cop_names.uniq.sort end |
#match_captures ⇒ Object
Returns match captures to directive comment pattern
131 132 133 134 135 136 137 138 139 |
# File 'lib/rubocop/directive_comment.rb', line 131 def match_captures @match_captures ||= @match_data && begin captures = @match_data.captures mode = captures[0] # COPS_PATTERN is at captures[1], PUSH_POP_ARGS_PATTERN is at captures[4] cops = captures[1] || captures[4] [mode, cops] end end |
#missing_cop_name? ⇒ Boolean
Checks if the directive comment is missing a cop name
81 82 83 84 85 |
# File 'lib/rubocop/directive_comment.rb', line 81 def missing_cop_name? return false if push? || pop? MALFORMED_DIRECTIVE_WITHOUT_COP_NAME_REGEXP.match?(comment.text) end |
#overridden_by_department?(cop) ⇒ Boolean
Checks if cop department has already used in directive comment
208 209 210 |
# File 'lib/rubocop/directive_comment.rb', line 208 def overridden_by_department?(cop) in_directive_department?(cop) && raw_cop_names.include?(cop) end |
#pop? ⇒ Boolean
Checks if this directive is a pop
162 163 164 |
# File 'lib/rubocop/directive_comment.rb', line 162 def pop? mode == 'pop' end |
#push? ⇒ Boolean
Checks if this directive is a push
157 158 159 |
# File 'lib/rubocop/directive_comment.rb', line 157 def push? mode == 'push' end |
#push_args ⇒ Object
Returns the push arguments as a hash of cop names with their operations
167 168 169 |
# File 'lib/rubocop/directive_comment.rb', line 167 def push_args @push_args ||= parse_push_args end |
#range ⇒ Object
109 110 111 112 113 114 115 |
# File 'lib/rubocop/directive_comment.rb', line 109 def range match = comment.text.match(DIRECTIVE_COMMENT_REGEXP) begin_pos = comment.source_range.begin_pos Parser::Source::Range.new( comment.source_range.source_buffer, begin_pos + match.begin(0), begin_pos + match.end(0) ) end |
#range_with_reason ⇒ Object
#range stops at the cop list, so a -- reason sits outside it. The reason documents the
directive and means nothing once the directive is gone, so removal has to cover both. Any
other trailing text is an ordinary comment and is left alone.
120 121 122 123 124 125 126 127 128 |
# File 'lib/rubocop/directive_comment.rb', line 120 def range_with_reason directive_range = range trailing = Parser::Source::Range.new( comment.source_range.source_buffer, directive_range.end_pos, comment.source_range.end_pos ) return directive_range unless trailing.source.lstrip.start_with?(TRAILING_COMMENT_MARKER) directive_range.with(end_pos: comment.source_range.end_pos) end |
#raw_cop_names ⇒ Object
Returns an array of cops for this directive comment, without resolving departments
192 193 194 |
# File 'lib/rubocop/directive_comment.rb', line 192 def raw_cop_names @raw_cop_names ||= (cops || '').split(/,\s*/) end |
#reason ⇒ Object
The text of the directive's optional -- trailing comment, or nil
when there is none.
89 90 91 92 93 94 95 96 97 |
# File 'lib/rubocop/directive_comment.rb', line 89 def reason return unless @match_data tail = @match_data.post_match.lstrip return unless tail.start_with?(TRAILING_COMMENT_MARKER) reason = tail.delete_prefix(TRAILING_COMMENT_MARKER).strip reason unless reason.empty? end |
#single_line? ⇒ Boolean
Checks if this directive relates to single line
100 101 102 |
# File 'lib/rubocop/directive_comment.rb', line 100 def single_line? !comment.text.start_with?(DIRECTIVE_COMMENT_REGEXP) end |
#start_with_marker? ⇒ Boolean
Checks if the comment starts with # rubocop: marker
67 68 69 |
# File 'lib/rubocop/directive_comment.rb', line 67 def start_with_marker? comment.text.start_with?(DIRECTIVE_MARKER_REGEXP) end |